Skip to content

Commit 05a58a8

Browse files
authored
Update RequiredIf Validator to accept UDF/closure (#79)
The closure should return boolean (true/false). True=Key is required. False=key is not required.
1 parent f81e904 commit 05a58a8

File tree

2 files changed

+91
-13
lines changed

2 files changed

+91
-13
lines changed

models/validators/RequiredIfValidator.cfc

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ component
3838
struct rules
3939
){
4040
var isRequired = true;
41+
var errorMetadata = {};
4142

4243
// If you passed in simple data, simply check that the target field has a value
4344
if ( isSimpleValue( arguments.validationData ) && len( arguments.validationData ) ) {
@@ -60,13 +61,27 @@ component
6061
.reduce( function( result, key, value ){
6162
return ( arguments.value && arguments.result );
6263
}, true );
63-
} else {
64-
validationResult.addError(
64+
// If passed a UDF/closure
65+
} else if (
66+
isCustomFunction( arguments.validationData ) ||
67+
isClosure( arguments.validationData )
68+
) {
69+
70+
// Validate against the UDF/closure
71+
var isRequired = arguments.validationData(
72+
isNull( arguments.targetValue ) ? javacast( "null", "" ) : arguments.targetValue,
73+
arguments.target,
74+
errorMetadata
75+
);
76+
77+
} else {
78+
79+
validationResult.addError(
6580
validationResult.newError(
6681
message = "The target for RequiredIf must be a simple field name or a struct of field to target value pairs.",
6782
field = arguments.field,
6883
validationType = getName(),
69-
rejectedValue = arguments.validationData,
84+
rejectedValue = isSimpleValue( arguments.validationData ) ? arguments.validationData : "",
7085
validationData = arguments.validationData
7186
)
7287
);
@@ -94,7 +109,9 @@ component
94109
validationData : arguments.validationData
95110
};
96111

97-
validationResult.addError( validationResult.newError( argumentCollection = args ) );
112+
validationResult.addError(
113+
validationResult.newError( argumentCollection = args ).setErrorMetadata( errorMetadata )
114+
);
98115
return false;
99116
}
100117

test-harness/tests/specs/validators/RequiredIfValidatorTest.cfc

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,78 @@ component extends="coldbox.system.testing.BaseModelTest" model="cbvalidation.mod
106106

107107
expect( model.validate( result, mock, "testField", "", "name" ) ).toBeFalse();
108108

109-
// expect(
110-
// model.validate(
111-
// result,
112-
// mock,
113-
// "testField",
114-
// "",
115-
// "missing"
116-
// )
117-
// ).toBeTrue();
109+
expect(
110+
model.validate(
111+
result,
112+
mock,
113+
"testField",
114+
"",
115+
"missing"
116+
)
117+
).toBeTrue();
118+
} );
119+
it( "can accept a closure as validationData", function(){
120+
var mock = createStub()
121+
.$( "getName", "luis" )
122+
.$( "getRole", "admin" )
123+
.$( "getMissing", javacast( "null", "" ) );
124+
var result = createMock( "cbvalidation.models.result.ValidationResult" ).init();
125+
126+
expect(
127+
model.validate(
128+
result,
129+
mock,
130+
"testField",
131+
"",
132+
isRequired1
133+
) ).toBeFalse();
134+
135+
expect(
136+
model.validate(
137+
result,
138+
mock,
139+
"testField",
140+
"",
141+
isRequired2
142+
)
143+
).toBeTrue();
144+
} );
145+
it( "can use custom error metadata", function(){
146+
var mock = createStub()
147+
.$( "getName", "luis" )
148+
.$( "getRole", "admin" )
149+
.$( "getMissing", javacast( "null", "" ) );
150+
var result = createMock( "cbvalidation.models.result.ValidationResult" ).init();
151+
152+
expect(
153+
model.validate(
154+
result,
155+
mock,
156+
"testField",
157+
"",
158+
isRequired3
159+
) ).toBeFalse();
160+
161+
var errorMetadata = result.getErrors()[ 1 ].getErrorMetadata();
162+
163+
expect( errorMetaData ).toHaveKey( "customMessage" );
164+
expect( errorMetaData.customMessage ).toBe( "This is custom data" );
165+
118166
} );
119167
} );
120168
}
121169

170+
private function isRequired1( value, target, errorMetadata ){
171+
return true;
172+
}
173+
174+
private function isRequired2( value, target, errorMetadata ){
175+
return false;
176+
}
177+
178+
private function isRequired3( value, target, errorMetadata ){
179+
arguments.errorMetadata[ "customMessage" ] = "This is custom data";
180+
return true;
181+
}
182+
122183
}

0 commit comments

Comments
 (0)