@@ -111,6 +111,11 @@ describe('StringOperatorSchema', () => {
111111 expect ( ( ) => StringOperatorSchema . parse ( filter ) ) . not . toThrow ( ) ;
112112 } ) ;
113113
114+ it ( 'should accept $notContains operator' , ( ) => {
115+ const filter = { $notContains : 'spam' } ;
116+ expect ( ( ) => StringOperatorSchema . parse ( filter ) ) . not . toThrow ( ) ;
117+ } ) ;
118+
114119 it ( 'should accept $endsWith operator' , ( ) => {
115120 const filter = { $endsWith : '.pdf' } ;
116121 expect ( ( ) => StringOperatorSchema . parse ( filter ) ) . not . toThrow ( ) ;
@@ -826,6 +831,11 @@ describe('parseFilterAST', () => {
826831 expect ( parseFilterAST ( [ 'name' , 'like' , 'John' ] ) ) . toEqual ( { name : { $contains : 'John' } } ) ;
827832 } ) ;
828833
834+ it ( 'should convert notcontains/not_contains operator' , ( ) => {
835+ expect ( parseFilterAST ( [ 'name' , 'notcontains' , 'spam' ] ) ) . toEqual ( { name : { $notContains : 'spam' } } ) ;
836+ expect ( parseFilterAST ( [ 'name' , 'not_contains' , 'spam' ] ) ) . toEqual ( { name : { $notContains : 'spam' } } ) ;
837+ } ) ;
838+
829839 it ( 'should convert startswith operator' , ( ) => {
830840 expect ( parseFilterAST ( [ 'name' , 'startswith' , 'A' ] ) ) . toEqual ( { name : { $startsWith : 'A' } } ) ;
831841 expect ( parseFilterAST ( [ 'name' , 'starts_with' , 'A' ] ) ) . toEqual ( { name : { $startsWith : 'A' } } ) ;
@@ -948,6 +958,8 @@ describe('isFilterAST', () => {
948958 expect ( isFilterAST ( [ 'age' , '>=' , 18 ] ) ) . toBe ( true ) ;
949959 expect ( isFilterAST ( [ 'role' , 'in' , [ 'admin' , 'editor' ] ] ) ) . toBe ( true ) ;
950960 expect ( isFilterAST ( [ 'name' , 'contains' , 'John' ] ) ) . toBe ( true ) ;
961+ expect ( isFilterAST ( [ 'name' , 'notcontains' , 'spam' ] ) ) . toBe ( true ) ;
962+ expect ( isFilterAST ( [ 'name' , 'not_contains' , 'spam' ] ) ) . toBe ( true ) ;
951963 expect ( isFilterAST ( [ 'name' , 'like' , 'John' ] ) ) . toBe ( true ) ;
952964 expect ( isFilterAST ( [ 'created_at' , 'between' , [ '2024-01-01' , '2024-12-31' ] ] ) ) . toBe ( true ) ;
953965 expect ( isFilterAST ( [ 'deleted_at' , 'is_null' , null ] ) ) . toBe ( true ) ;
@@ -1009,7 +1021,7 @@ describe('isFilterAST', () => {
10091021describe ( 'VALID_AST_OPERATORS' , ( ) => {
10101022 it ( 'should contain all standard comparison operators' , ( ) => {
10111023 const expected = [ '=' , '==' , '!=' , '<>' , '>' , '>=' , '<' , '<=' , 'in' , 'nin' , 'not_in' ,
1012- 'contains' , 'like' , 'startswith' , 'starts_with' , 'endswith' , 'ends_with' ,
1024+ 'contains' , 'notcontains' , 'not_contains' , ' like', 'startswith' , 'starts_with' , 'endswith' , 'ends_with' ,
10131025 'between' , 'is_null' , 'is_not_null' ] ;
10141026 for ( const op of expected ) {
10151027 expect ( VALID_AST_OPERATORS . has ( op ) ) . toBe ( true ) ;
0 commit comments