From 76e9b59b4b34932bcd857e1d7bc747fe6a34e195 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 29 May 2015 15:06:40 -0400 Subject: [PATCH] Split out the RulesChecker into a working object. Add some additional tests for the rules checkers as well. --- src/Datasource/RulesChecker.php | 41 +++- src/ORM/RulesChecker.php | 39 ---- .../TestCase/Datasource/RulesCheckerTest.php | 202 ++++++++++++++++++ 3 files changed, 242 insertions(+), 40 deletions(-) create mode 100644 tests/TestCase/Datasource/RulesCheckerTest.php diff --git a/src/Datasource/RulesChecker.php b/src/Datasource/RulesChecker.php index fe1a3b09756..60571c92ae9 100644 --- a/src/Datasource/RulesChecker.php +++ b/src/Datasource/RulesChecker.php @@ -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'); @@ -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; + }; + } } diff --git a/src/ORM/RulesChecker.php b/src/ORM/RulesChecker.php index c84172ba7d3..09eab09f48b 100644 --- a/src/ORM/RulesChecker.php +++ b/src/ORM/RulesChecker.php @@ -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; - }; - } } diff --git a/tests/TestCase/Datasource/RulesCheckerTest.php b/tests/TestCase/Datasource/RulesCheckerTest.php new file mode 100644 index 00000000000..58517bef747 --- /dev/null +++ b/tests/TestCase/Datasource/RulesCheckerTest.php @@ -0,0 +1,202 @@ + '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()); + } +}