Skip to content

Commit 9d7197c

Browse files
authored
Merge pull request #48 from homestar9/feature/udf-and-method-metadata
New Feature: Allow UDF and Method Validators to Utilize Error Metadata
2 parents 98048aa + cb7a16d commit 9d7197c

File tree

5 files changed

+136
-8
lines changed

5 files changed

+136
-8
lines changed

models/validators/MethodValidator.cfc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ component
3535
any validationData,
3636
struct rules
3737
){
38+
var errorMetadata = {};
39+
40+
// return true if no data to check, type needs a data element to be checked.
41+
if ( isNull( arguments.targetValue ) || isNullOrEmpty( arguments.targetValue ) ) {
42+
return true;
43+
}
44+
3845
// return true if no data to check, type needs a data element to be checked.
3946
if ( isNull( arguments.targetValue ) || isNullOrEmpty( arguments.targetValue ) ) {
4047
return true;
@@ -45,7 +52,7 @@ component
4552
invoke(
4653
arguments.target,
4754
arguments.validationData,
48-
[ arguments.targetValue ]
55+
[ arguments.targetValue, errorMetadata ]
4956
)
5057
) {
5158
return true;
@@ -59,7 +66,9 @@ component
5966
validationData : arguments.validationData
6067
};
6168

62-
validationResult.addError( validationResult.newError( argumentCollection = args ) );
69+
validationResult.addError(
70+
validationResult.newError( argumentCollection = args ).setErrorMetadata( errorMetadata )
71+
);
6372
return false;
6473
}
6574

models/validators/UDFValidator.cfc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ component
3535
any validationData,
3636
struct rules
3737
){
38+
var errorMetadata = {};
39+
3840
// Validate against the UDF/closure
3941
var passed = arguments.validationData(
4042
isNull( arguments.targetValue ) ? javacast( "null", "" ) : arguments.targetValue,
41-
arguments.target
43+
arguments.target,
44+
errorMetadata
4245
);
4346

4447
if ( passed ) {
@@ -53,7 +56,9 @@ component
5356
validationData : arguments.validationData
5457
};
5558

56-
validationResult.addError( validationResult.newError( argumentCollection = args ) );
59+
validationResult.addError(
60+
validationResult.newError( argumentCollection = args ).setErrorMetadata( errorMetadata )
61+
);
5762

5863
return false;
5964
}

test-harness/handlers/Main.cfc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/**
22
* My Event Handler Hint
33
*/
44
component {
@@ -104,6 +104,21 @@ component {
104104
);
105105

106106
return "Validated";
107+
}
108+
109+
110+
/**
111+
* validateOnly
112+
*/
113+
function validateOnly( event, rc, prc){
114+
115+
var oModel = populateModel( "User" );
116+
117+
// validate
118+
prc.result = validate( oModel );
119+
120+
return "Validated";
121+
107122
}
108123

109124

test-harness/models/User.cfc

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ component accessors="true" {
22

33
property name="username" default="";
44
property name="password" default="";
5-
property name="email" default="";
5+
property name="email" default="";
6+
property name="status" default="";
7+
property name="type" default="1";
68

79
this.constraintProfiles = {
810
new : "username,password,email",
@@ -11,11 +13,31 @@ component accessors="true" {
1113
this.constraints = {
1214
username : { required : true, size : "2..20" },
1315
password : { required : true, size : "2..20" },
14-
email : { required : true, type : "email" }
16+
email : { required : true, type : "email" },
17+
status : {
18+
required : false,
19+
udf : function( value, target, metadata ) {
20+
metadata[ "custom" ] = "this is some custom udf metadata";
21+
metadata[ "customMessage" ] = "This is a custom error message from within the udf";
22+
return listFind( "1,2,3", value );
23+
},
24+
udfMessage : "{customMessage}"
25+
},
26+
type : {
27+
required : false,
28+
method : "isUserValid",
29+
methodMessage : "{customMessage}"
30+
}
1531
};
1632

1733
function init(){
1834
return this;
19-
}
35+
}
36+
37+
function isUserValid( value, metadata ) {
38+
metadata[ "custom" ] = "this is some custom method metadata";
39+
metadata[ "customMessage" ] = "This is a custom error message from within the method";
40+
return listFind( "1,2,3", value );
41+
}
2042

2143
}

test-harness/tests/specs/ValidationIntegrations.cfc

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" {
8080
username : "luis",
8181
password : "luis",
8282
email : "[email protected]",
83+
status : 1,
8384
bogus : now(),
8485
anotherBogus : now()
8586
},
@@ -146,6 +147,82 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" {
146147
} );
147148
} );
148149
} );
150+
151+
152+
story( "I want to access error metadata in UDF and method validators", function(){
153+
given( "invalid data", function(){
154+
then( "it should allow access to custom udf metadata", function(){
155+
var e = this.request(
156+
route = "/main/validateOnly",
157+
params = {
158+
username : "luis",
159+
email : "[email protected]",
160+
password : "luis"
161+
},
162+
method = "post"
163+
);
164+
165+
var result = e.getPrivateValue( "result" );
166+
167+
expect( result.getErrors().len() ).toBe( 1 );
168+
expect( result.getErrors()[ 1 ].getValidationType() ).toBe( "UDF" );
169+
expect( result.getErrors()[ 1 ].getErrorMetaData() ).toHaveKey( "custom" );
170+
} );
171+
then( "it should allow udf generated error messages based on metadata", function(){
172+
var e = this.request(
173+
route = "/main/validateOnly",
174+
params = {
175+
username : "luis",
176+
email : "[email protected]",
177+
password : "luis"
178+
},
179+
method = "post"
180+
);
181+
182+
var result = e.getPrivateValue( "result" );
183+
expect( result.getErrors()[ 1 ].getMessage() ).toBe(
184+
"This is a custom error message from within the udf"
185+
);
186+
} );
187+
then( "it should allow access to custom method metadata", function(){
188+
var e = this.request(
189+
route = "/main/validateOnly",
190+
params = {
191+
username : "luis",
192+
email : "[email protected]",
193+
password : "luis",
194+
status : 1,
195+
type : 4 // should not validate
196+
},
197+
method = "post"
198+
);
199+
200+
var result = e.getPrivateValue( "result" );
201+
202+
expect( result.getErrors().len() ).toBe( 1 );
203+
expect( result.getErrors()[ 1 ].getValidationType() ).toBe( "method" );
204+
expect( result.getErrors()[ 1 ].getErrorMetaData() ).toHaveKey( "custom" );
205+
} );
206+
then( "it should allow method generated error messages based on metadata", function(){
207+
var e = this.request(
208+
route = "/main/validateOnly",
209+
params = {
210+
username : "luis",
211+
email : "[email protected]",
212+
password : "luis",
213+
status : 1,
214+
type : 4 // should not validate
215+
},
216+
method = "post"
217+
);
218+
219+
var result = e.getPrivateValue( "result" );
220+
expect( result.getErrors()[ 1 ].getMessage() ).toBe(
221+
"This is a custom error message from within the method"
222+
);
223+
} );
224+
} );
225+
} );
149226
}
150227

151228
}

0 commit comments

Comments
 (0)