1- import { createTestClient } from '@zenstackhq/testtools' ;
1+ import { createTestClient , loadSchemaWithError } from '@zenstackhq/testtools' ;
22import { describe , expect , it } from 'vitest' ;
33
44describe ( 'Custom validation tests' , ( ) => {
@@ -15,25 +15,28 @@ describe('Custom validation tests', () => {
1515 int1 Int?
1616 list1 Int[]
1717 list2 Int[]
18+ list3 Int[]
1819
1920 @@validate(
20- (str1 == null || length(str1, 8, 10))
21+ (str1 == null || ( length(str1) >= 8 && length(str1) <= 10))
2122 && (int1 == null || (int1 > 1 && int1 < 4)),
2223 'invalid fields')
2324
2425 @@validate(str1 == null || (startsWith(str1, 'a') && endsWith(str1, 'm') && contains(str1, 'b')), 'invalid fields')
2526
2627 @@validate(str2 == null || regex(str2, '^x.*z$'), 'invalid str2')
2728
28- @@validate(str3 == null || email (str3), 'invalid str3')
29+ @@validate(str3 == null || isEmail (str3), 'invalid str3')
2930
30- @@validate(str4 == null || url (str4), 'invalid str4')
31+ @@validate(str4 == null || isUrl (str4), 'invalid str4')
3132
32- @@validate(str5 == null || datetime (str5), 'invalid str5')
33+ @@validate(str5 == null || isDateTime (str5), 'invalid str5')
3334
3435 @@validate(list1 == null || (has(list1, 1) && hasSome(list1, [2, 3]) && hasEvery(list1, [4, 5])), 'invalid list1')
3536
3637 @@validate(list2 == null || isEmpty(list2), 'invalid list2', ['x', 'y'])
38+
39+ @@validate(list3 == null || length(list3) <2 , 'invalid list3')
3740 }
3841 ` ,
3942 { provider : 'postgresql' } ,
@@ -93,6 +96,9 @@ describe('Custom validation tests', () => {
9396 }
9497 expect ( thrown ) . toBe ( true ) ;
9598
99+ // validates list length
100+ await expect ( _t ( { list3 : [ 1 , 2 ] } ) ) . toBeRejectedByValidation ( [ 'invalid list3' ] ) ;
101+
96102 // satisfies all
97103 await expect (
98104 _t ( {
@@ -104,6 +110,7 @@ describe('Custom validation tests', () => {
104110 int1 : 2 ,
105111 list1 : [ 1 , 2 , 4 , 5 ] ,
106112 list2 : [ ] ,
113+ list3 : [ 1 ] ,
107114 } ) ,
108115 ) . toResolveTruthy ( ) ;
109116 }
@@ -115,7 +122,7 @@ describe('Custom validation tests', () => {
115122 model User {
116123 id Int @id @default(autoincrement())
117124 email String @unique @email
118- @@validate(length(email, 8) )
125+ @@validate(length(email) >= 8 )
119126 @@allow('all', true)
120127 }
121128 ` ,
@@ -170,4 +177,61 @@ describe('Custom validation tests', () => {
170177 } ) ,
171178 ) . toBeRejectedByValidation ( ) ;
172179 } ) ;
180+
181+ it ( 'checks arg type for validation functions' , async ( ) => {
182+ // length() on relation field
183+ await loadSchemaWithError (
184+ `
185+ model Foo {
186+ id Int @id @default(autoincrement())
187+ bars Bar[]
188+ @@validate(length(bars) > 0)
189+ }
190+
191+ model Bar {
192+ id Int @id @default(autoincrement())
193+ foo Foo @relation(fields: [fooId], references: [id])
194+ fooId Int
195+ }
196+ ` ,
197+ 'argument must be a string or list field' ,
198+ ) ;
199+
200+ // length() on non-string/list field
201+ await loadSchemaWithError (
202+ `
203+ model Foo {
204+ id Int @id @default(autoincrement())
205+ x Int
206+ @@validate(length(x) > 0)
207+ }
208+ ` ,
209+ 'argument must be a string or list field' ,
210+ ) ;
211+
212+ // invalid regex pattern
213+ await loadSchemaWithError (
214+ `
215+ model Foo {
216+ id Int @id @default(autoincrement())
217+ x String
218+ @@validate(regex(x, '[abc'))
219+ }
220+ ` ,
221+ 'invalid regular expression' ,
222+ ) ;
223+
224+ // using field as regex pattern
225+ await loadSchemaWithError (
226+ `
227+ model Foo {
228+ id Int @id @default(autoincrement())
229+ x String
230+ y String
231+ @@validate(regex(x, y))
232+ }
233+ ` ,
234+ 'second argument must be a string literal' ,
235+ ) ;
236+ } ) ;
173237} ) ;
0 commit comments