Skip to content

Commit

Permalink
Split out the RulesChecker into a working object.
Browse files Browse the repository at this point in the history
Add some additional tests for the rules checkers as well.
  • Loading branch information
markstory committed May 29, 2015
1 parent 19c0c7c commit 76e9b59
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 40 deletions.
41 changes: 40 additions & 1 deletion src/Datasource/RulesChecker.php
Expand Up @@ -109,7 +109,7 @@ class RulesChecker
*
* @param array $options The options to pass to every rule
*/
public function __construct(array $options)
public function __construct(array $options = [])
{
$this->_options = $options;
$this->_useI18n = function_exists('__d');
Expand Down Expand Up @@ -293,4 +293,43 @@ public function checkDelete(EntityInterface $entity, array $options = [])
}
return $success;
}

/**
* Utility method for decorating any callable so that if it returns false, the correct
* property in the entity is marked as invalid.
*
* @param callable $rule The rule to decorate
* @param string $name The alias for a rule.
* @param array $options The options containing the error message and field
* @return callable
*/
protected function _addError($rule, $name, $options)
{
if (is_array($name)) {
$options = $name;
$name = null;
}

return function ($entity, $scope) use ($rule, $name, $options) {
$pass = $rule($entity, $options + $scope);
if ($pass === true || empty($options['errorField'])) {
return $pass === true;
}

$message = 'invalid';
if (isset($options['message'])) {
$message = $options['message'];
}
if (is_string($pass)) {
$message = $pass;
}
if ($name) {
$message = [$name => $message];
} else {
$message = [$message];
}
$entity->errors($options['errorField'], $message);
return $pass === true;
};
}
}
39 changes: 0 additions & 39 deletions src/ORM/RulesChecker.php
Expand Up @@ -89,43 +89,4 @@ public function existsIn($field, $table, $message = null)
$errorField = is_string($field) ? $field : current($field);
return $this->_addError(new ExistsIn($field, $table), '_existsIn', compact('errorField', 'message'));
}

/**
* Utility method for decorating any callable so that if it returns false, the correct
* property in the entity is marked as invalid.
*
* @param callable $rule The rule to decorate
* @param string $name The alias for a rule.
* @param array $options The options containing the error message and field
* @return callable
*/
protected function _addError($rule, $name, $options)
{
if (is_array($name)) {
$options = $name;
$name = null;
}

return function ($entity, $scope) use ($rule, $name, $options) {
$pass = $rule($entity, $options + $scope);
if ($pass === true || empty($options['errorField'])) {
return $pass === true;
}

$message = 'invalid';
if (isset($options['message'])) {
$message = $options['message'];
}
if (is_string($pass)) {
$message = $pass;
}
if ($name) {
$message = [$name => $message];
} else {
$message = [$message];
}
$entity->errors($options['errorField'], $message);
return $pass === true;
};
}
}
202 changes: 202 additions & 0 deletions tests/TestCase/Datasource/RulesCheckerTest.php
@@ -0,0 +1,202 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.7
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Test\TestCase\Datasource;

use Cake\ORM\Entity;
use Cake\Datasource\RulesChecker;
use Cake\TestSuite\TestCase;

/**
* Tests the integration between the ORM and the domain checker
*/
class RulesCheckerTest extends TestCase
{
/**
* Test adding rule for update mode
*
* @return void
*/
public function testAddingRuleDeleteMode()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->addDelete(
function () {
return false;
},
'ruleName',
['errorField' => 'name']
);

$this->assertTrue($rules->check($entity, RulesChecker::CREATE));
$this->assertEmpty($entity->errors());
$this->assertTrue($rules->check($entity, RulesChecker::UPDATE));
$this->assertEmpty($entity->errors());

$this->assertFalse($rules->check($entity, RulesChecker::DELETE));
$this->assertEquals(['ruleName' => 'invalid'], $entity->errors('name'));
}

/**
* Test adding rule for update mode
*
* @return void
*/
public function testAddingRuleUpdateMode()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->addUpdate(
function () {
return false;
},
'ruleName',
['errorField' => 'name']
);

$this->assertTrue($rules->check($entity, RulesChecker::CREATE));
$this->assertEmpty($entity->errors());
$this->assertTrue($rules->check($entity, RulesChecker::DELETE));
$this->assertEmpty($entity->errors());

$this->assertFalse($rules->check($entity, RulesChecker::UPDATE));
$this->assertEquals(['ruleName' => 'invalid'], $entity->errors('name'));
}

/**
* Test adding rule for create mode
*
* @return void
*/
public function testAddingRuleCreateMode()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->addCreate(
function () {
return false;
},
'ruleName',
['errorField' => 'name']
);

$this->assertTrue($rules->check($entity, RulesChecker::UPDATE));
$this->assertEmpty($entity->errors());
$this->assertTrue($rules->check($entity, RulesChecker::DELETE));
$this->assertEmpty($entity->errors());

$this->assertFalse($rules->check($entity, RulesChecker::CREATE));
$this->assertEquals(['ruleName' => 'invalid'], $entity->errors('name'));
}

/**
* Test adding rule with name
*
* @return void
*/
public function testAddingRuleWithName()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->add(
function () {
return false;
},
'ruleName',
['errorField' => 'name']
);

$this->assertFalse($rules->check($entity, RulesChecker::CREATE));
$this->assertEquals(['ruleName' => 'invalid'], $entity->errors('name'));
}

/**
* Test that returnned error messages work.
*
* @return void
*/
public function testAddWithErrorMessage()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->add(
function () {
return 'worst thing ever';
},
['errorField' => 'name']
);

$this->assertFalse($rules->check($entity, RulesChecker::CREATE));
$this->assertEquals(['worst thing ever'], $entity->errors('name'));
}

/**
* Test that returnned error messages work.
*
* @return void
*/
public function testAddWithMessageOption()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->add(
function () {
return false;
},
['message' => 'this is bad', 'errorField' => 'name']
);

$this->assertFalse($rules->check($entity, RulesChecker::CREATE));
$this->assertEquals(['this is bad'], $entity->errors('name'));
}

/**
* Test that returnned error messages work.
*
* @return void
*/
public function testAddWithoutFields()
{
$entity = new Entity([
'name' => 'larry'
]);

$rules = new RulesChecker();
$rules->add(function () {
return false;
});

$this->assertFalse($rules->check($entity, RulesChecker::CREATE));
$this->assertEmpty($entity->errors());
}
}

0 comments on commit 76e9b59

Please sign in to comment.