Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions models/Component.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ component output="true" accessors="true" {
// Determine if component should be lazy loaded
// If lazy parameter is explicitly provided, use that value
// Otherwise, use the component's lazy preference
local.shouldLazyLoad = isNull( arguments.lazy ) ?
local.shouldLazyLoad = isNull( arguments.lazy ) ?
local.instance._getLazyLoad() : // Use component's preference if no explicit parameter
arguments.lazy; // Use explicit parameter value

Expand Down Expand Up @@ -1115,7 +1115,9 @@ component output="true" accessors="true" {
function _getConstraints(){
if ( variables.keyExists( "constraints" ) ) {
return variables.constraints;
}
}else if ( structKeyExists( this, "constraints" ) ) {
return this.constraints;
}
return [:];
}

Expand Down
8 changes: 6 additions & 2 deletions models/services/ValidationService.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ component accessors="true" singleton {
* @return ValidationResult The result of the validation operation.
*/
function validate( wire, target, fields, constraints, locale, excludeFields, includeFields, profiles ){
arguments.target = isNull( arguments.target ) ? arguments.wire._getDataProperties() : arguments.target;
arguments.constraints = isNull( arguments.constraints ) ? arguments.wire._getConstraints() : arguments.constraints;
if( isNull( arguments.target ) ){
// if no target is provided, default to the wire's data properties
arguments.target = arguments.wire._getDataProperties();
// use the wire's constraints if explicit constraints are not provided
arguments.constraints = isNull( arguments.constraints ) ? arguments.wire._getConstraints() : arguments.constraints
Comment thread
grantcopley marked this conversation as resolved.
}
return getManager().validate( argumentCollection = arguments );
}

Expand Down
21 changes: 21 additions & 0 deletions test-harness/models/validationTest.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
component accessors="true" {

property name="FirstName";
property name="LastName";

this.constraints = {
FirstName : {
required : true,
requiredMessage : "First name is required",
size : "2..50",
sizeMessage : "First name must be 2-50 characters"
},
LastName : {
required : true,
requiredMessage : "Last name is required",
size : "2..50",
sizeMessage : "Last name must be 2-50 characters"
}
Comment thread
grantcopley marked this conversation as resolved.
};

}
27 changes: 22 additions & 5 deletions test-harness/tests/specs/CBWIRESpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,23 @@ component extends="coldbox.system.testing.BaseTestCase" {
expect( renderedHtml ).toInclude( 'Some&##x20;text&##x20;with&##x20;&##x5c;"quotes' );
});

it("should get constraints when set using this.constraints= ", function() {
var testValidationComponent = getInstance("wires.test.validation.validateConstraints1");
var constraints = testValidationComponent._getConstraints();
expect( constraints ).toBeTypeOf( "struct" );
expect( constraints ).toHaveLength( 1 );
expect( constraints ).toHaveKey( "firstname" );
});

it("should get constraints when set using constraints= ", function() {
var testValidationComponent = getInstance("wires.test.validation.validateConstraints2");
var constraints = testValidationComponent._getConstraints();
expect( constraints ).toBeTypeOf( "struct" );
expect( constraints ).toHaveLength( 1 );
expect( constraints ).toHaveKey( "firstname" );
});


});
Comment thread
grantcopley marked this conversation as resolved.
Outdated

describe("Incoming Requests", function() {
Expand Down Expand Up @@ -727,7 +744,7 @@ component extends="coldbox.system.testing.BaseTestCase" {
var settings = getInstance( "coldbox:modulesettings:cbwire" );
var originalSetting = settings.csrfEnabled;
settings.csrfEnabled = false;

var payload = incomingRequest(
memo = {
"name": "TestComponent",
Expand All @@ -747,12 +764,12 @@ component extends="coldbox.system.testing.BaseTestCase" {
updates = {},
csrfToken = "badToken"
);

// Should not throw an error even with bad token when CSRF is disabled
var response = cbwireController.handleRequest( payload, event );
expect( isStruct( response ) ).toBeTrue();
expect( response.components[1].effects.html ).toInclude( "CBWIRE Slays!" );

// Restore original setting
settings.csrfEnabled = originalSetting;
} );
Expand All @@ -761,10 +778,10 @@ component extends="coldbox.system.testing.BaseTestCase" {
var settings = getInstance( "coldbox:modulesettings:cbwire" );
var originalSetting = settings.csrfEnabled;
settings.csrfEnabled = false;

var token = cbwireController.generateCSRFToken();
expect( token ).toBe( "" );

// Restore original setting
settings.csrfEnabled = originalSetting;
} );
Expand Down
80 changes: 79 additions & 1 deletion test-harness/tests/specs/unit/services/ValidationServiceSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ component extends="coldbox.system.testing.BaseTestCase" {
});

describe( "validate()", function() {
it( "should validate with given target and constraints", function() {

it( "should validate with given target and constraints", function() {
var wire = {};
var target = { "foo": "bar" };
var constraints = { "foo": { "required": true } };
Expand All @@ -61,6 +62,83 @@ component extends="coldbox.system.testing.BaseTestCase" {
var result = validationService.validate( wire );
expect( result ).toHaveKey( "ok" );
});

it( "shoud validate an object other than the wire itself", function() {
Comment thread
grantcopley marked this conversation as resolved.
Outdated
var oValidationTest = getInstance( "validationTest" );
var wire = prepareMock( createStub() );
wire.$( "_getDataProperties", { "bar": "baz" } );
wire.$( "_getConstraints", { "bar": { "required": true } } );
// mock the validate method to return the arguments passed to it so that
// we can validate that the correct mutation of the arguments is occurring
// in the validate() method of the service
mockValidationManager.$(
method = "validate",
callback = function() {
return arguments;
}
);
var result = validationService.validate( wire=wire, target=oValidationTest );
// validate that we do not have the wires constraints and that there
// are no constraints passed to validate() method so that the constraints
// from the object will be used
expect( result ).notToHaveKey( "constraints" );
// validate that we have a target passed into the validate method
expect( result ).toHaveKey( "target" );
// validate that the target contains the constraints from the object
expect( result.target ).toHaveKey( "constraints" );
expect( result.target.constraints ).toBeTypeOf( "struct" );
expect( result.target.constraints ).toHaveLength( 2 );
expect( result.target.constraints ).toHaveKey( "firstname" );
expect( result.target.constraints ).toHaveKey( "lastname" );
expect( result.target.constraints ).notToHaveKey( "bar" );
// get the metadata of the target to validate that it is the correct object and not the wire
var resultTargetMetaData = getMetadata( result.target );
// validate that the target metadata contains the name of the component (validationTest)
expect( resultTargetMetaData ).toHaveKey( "name" );
expect( resultTargetMetaData.name ).toInclude( "validationTest" );
});

it( "shoud validate an object other than the wire itself with custom validation constraints", function() {
Comment thread
grantcopley marked this conversation as resolved.
var oValidationTest = getInstance( "validationTest" );
var wire = prepareMock( createStub() );
wire.$( "_getDataProperties", { "bar": "baz" } );
wire.$( "_getConstraints", { "bar": { "required": true } } );
var customConstraints = {
password : {
required : true,
requiredMessage : "Password is required",
size : "8..50",
sizeMessage : "Password name must be 2-50 characters"
Comment thread
grantcopley marked this conversation as resolved.
Outdated
}
};
// mock the validate method to return the arguments passed to it so that
// we can validate that the correct mutation of the arguments is occurring
// in the validate() method of the service
mockValidationManager.$(
method = "validate",
callback = function() {
return arguments;
}
);
var result = validationService.validate( wire=wire, target=oValidationTest, constraints=customConstraints );
// validate that we do not have the wires constraints and that the constraints
// passed to the validate() method are the custom constraints and not the objects
// or wires constraints
expect( result ).toHaveKey( "constraints" );
expect( result.constraints ).toBeTypeOf( "struct" );
expect( result.constraints ).toHaveLength( 1 );
expect( result.constraints ).toHaveKey( "password" );
expect( result.constraints ).notToHaveKey( "lastname" );
expect( result.constraints ).notToHaveKey( "bar" );
// validate that we have a target passed into the validate method
expect( result ).toHaveKey( "target" );
// get the metadata of the target to validate that it is the correct object and not the wire
var resultTargetMetaData = getMetadata( result.target );
// validate that the target metadata contains the name of the component (validationTest)
expect( resultTargetMetaData ).toHaveKey( "name" );
expect( resultTargetMetaData.name ).toInclude( "validationTest" );
});

});

describe( "validateOrFail()", function() {
Expand Down
20 changes: 20 additions & 0 deletions test-harness/wires/test/validation/validateConstraints1.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
component extends="cbwire.models.Component" {

data = {
"firstname": "sdfsad",
"lastname": ""
}
Comment thread
grantcopley marked this conversation as resolved.
Outdated
/*
This components DOES use this.constraints=

The cbwire documentation states that you can define constraints using constraints=
https://cbwire.ortusbooks.com/features/form-validation

CBValidation documentation states that you define constraints using this.constraints=
https://coldbox-validation.ortusbooks.com/overview/declaring-constraints/domain-object
*/
this.constraints = {
"firstname": { required: true }
};

}
6 changes: 6 additions & 0 deletions test-harness/wires/test/validation/validateConstraints1.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<cfoutput>
<div>
<input wire:model="firstname" class="form-control" type="text" placeholder="First Name">
<button wire:click="submit">Submit</button>
</div>
</cfoutput>
20 changes: 20 additions & 0 deletions test-harness/wires/test/validation/validateConstraints2.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
component extends="cbwire.models.Component" {

data = {
"firstname": "sdfsad",
"lastname": ""
}
Comment thread
grantcopley marked this conversation as resolved.
Outdated
/*
This components DOES use constraints=

The cbwire documentation states that you can define constraints using constraints=
https://cbwire.ortusbooks.com/features/form-validation

CBValidation documentation states that you define constraints using this.constraints=
https://coldbox-validation.ortusbooks.com/overview/declaring-constraints/domain-object
*/
constraints = {
"firstname": { required: true }
};

}
6 changes: 6 additions & 0 deletions test-harness/wires/test/validation/validateConstraints2.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<cfoutput>
<div>
<input wire:model="firstname" class="form-control" type="text" placeholder="First Name">
<button wire:click="submit">Submit</button>
</div>
</cfoutput>
Loading