From c979feb762c26810029e83f3ede31c234916f3d3 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 2 May 2020 07:14:16 +0700 Subject: [PATCH] Fix is_unique and is_not_unique Rules on API Call at PostgreSQL --- system/Validation/Rules.php | 10 +- tests/system/Validation/RulesTest.php | 181 ++++++++++++++++++++ tests/system/Validation/UniqueRulesTest.php | 146 ---------------- 3 files changed, 189 insertions(+), 148 deletions(-) delete mode 100644 tests/system/Validation/UniqueRulesTest.php diff --git a/system/Validation/Rules.php b/system/Validation/Rules.php index 371634b40da8..9621676c5541 100644 --- a/system/Validation/Rules.php +++ b/system/Validation/Rules.php @@ -168,7 +168,10 @@ public function is_not_unique(string $str = null, string $field, array $data): b if (! empty($where_field) && ! empty($where_value)) { - $row = $row->where($where_field, $where_value); + if (! preg_match('/^\{(\w+)\}$/', $where_value)) + { + $row = $row->where($where_field, $where_value); + } } return (bool) ($row->get() @@ -228,7 +231,10 @@ public function is_unique(string $str = null, string $field, array $data): bool if (! empty($ignoreField) && ! empty($ignoreValue)) { - $row = $row->where("{$ignoreField} !=", $ignoreValue); + if (! preg_match('/^\{(\w+)\}$/', $ignoreValue)) + { + $row = $row->where("{$ignoreField} !=", $ignoreValue); + } } return (bool) ($row->get() diff --git a/tests/system/Validation/RulesTest.php b/tests/system/Validation/RulesTest.php index 4e0077f3a632..49ffdab26a41 100644 --- a/tests/system/Validation/RulesTest.php +++ b/tests/system/Validation/RulesTest.php @@ -4,6 +4,7 @@ use CodeIgniter\Test\CIDatabaseTestCase; use Config\Database; +use CodeIgniter\Validation\Rules; class RulesTest extends CIDatabaseTestCase { @@ -609,6 +610,186 @@ public function testIsUniqueIgnoresParams() //-------------------------------------------------------------------- + /** + * @group DatabaseLive + */ + public function testIsUniqueIgnoresParamsPlaceholders() + { + $this->hasInDatabase('user', [ + 'name' => 'Derek', + 'email' => 'derek@world.co.uk', + 'country' => 'GB', + ]); + + $db = Database::connect(); + $row = $db->table('user') + ->limit(1) + ->get() + ->getRow(); + + $data = [ + 'id' => $row->id, + 'email' => 'derek@world.co.uk', + ]; + + $this->validation->setRules([ + 'email' => 'is_unique[user.email,id,{id}]', + ]); + + $this->assertTrue($this->validation->run($data)); + } + + //-------------------------------------------------------------------- + + /** + * @group DatabaseLive + */ + public function testIsUniqueByManualRun() + { + $db = Database::connect(); + $db->table('user') + ->insert([ + 'name' => 'Developer A', + 'email' => 'deva@example.com', + 'country' => 'Elbonia', + ]); + + $this->assertFalse((new Rules())->is_unique('deva@example.com', 'user.email,id,{id}', [])); + } + + //-------------------------------------------------------------------- + + /** + * @group DatabaseLive + */ + public function testIsNotUniqueFalse() + { + $db = Database::connect(); + $db->table('user') + ->insert([ + 'name' => 'Derek Travis', + 'email' => 'derek@world.com', + 'country' => 'Elbonia', + ]); + + $data = [ + 'email' => 'derek1@world.com', + ]; + + $this->validation->setRules([ + 'email' => 'is_not_unique[user.email]', + ]); + + $this->assertFalse($this->validation->run($data)); + } + + //-------------------------------------------------------------------- + + /** + * @group DatabaseLive + */ + public function testIsNotUniqueTrue() + { + $db = Database::connect(); + $db->table('user') + ->insert([ + 'name' => 'Derek Travis', + 'email' => 'derek@world.com', + 'country' => 'Elbonia', + ]); + + $data = [ + 'email' => 'derek@world.com', + ]; + + $this->validation->setRules([ + 'email' => 'is_not_unique[user.email]', + ]); + + $this->assertTrue($this->validation->run($data)); + } + + //-------------------------------------------------------------------- + + /** + * @group DatabaseLive + */ + public function testIsNotUniqueIgnoresParams() + { + $db = Database::connect(); + $user = $db->table('user') + ->insert([ + 'name' => 'Developer A', + 'email' => 'deva@example.com', + 'country' => 'Elbonia', + ]); + $row = $db->table('user') + ->limit(1) + ->get() + ->getRow(); + + $data = [ + 'email' => 'derek@world.co.uk', + ]; + + $this->validation->setRules([ + 'email' => "is_not_unique[user.email,id,{$row->id}]", + ]); + + $this->assertFalse($this->validation->run($data)); + } + + //-------------------------------------------------------------------- + + /** + * @group DatabaseLive + */ + public function testIsNotUniqueIgnoresParamsPlaceholders() + { + $this->hasInDatabase('user', [ + 'name' => 'Derek', + 'email' => 'derek@world.co.uk', + 'country' => 'GB', + ]); + + $db = Database::connect(); + $row = $db->table('user') + ->limit(1) + ->get() + ->getRow(); + + $data = [ + 'id' => $row->id, + 'email' => 'derek@world.co.uk', + ]; + + $this->validation->setRules([ + 'email' => 'is_not_unique[user.email,id,{id}]', + ]); + + $this->assertTrue($this->validation->run($data)); + } + + //-------------------------------------------------------------------- + + /** + * @group DatabaseLive + */ + public function testIsNotUniqueByManualRun() + { + $db = Database::connect(); + $db->table('user') + ->insert([ + 'name' => 'Developer A', + 'email' => 'deva@example.com', + 'country' => 'Elbonia', + ]); + + $this->assertTrue((new Rules())->is_not_unique('deva@example.com', 'user.email,id,{id}', [])); + } + + //-------------------------------------------------------------------- + public function testMinLengthNull() { $data = [ diff --git a/tests/system/Validation/UniqueRulesTest.php b/tests/system/Validation/UniqueRulesTest.php deleted file mode 100644 index 1a1af678140f..000000000000 --- a/tests/system/Validation/UniqueRulesTest.php +++ /dev/null @@ -1,146 +0,0 @@ - [ - \CodeIgniter\Validation\Rules::class, - \CodeIgniter\Validation\FormatRules::class, - \CodeIgniter\Validation\FileRules::class, - \CodeIgniter\Validation\CreditCardRules::class, - \Tests\Support\Validation\TestRules::class, - ], - 'groupA' => [ - 'foo' => 'required|min_length[5]', - ], - 'groupA_errors' => [ - 'foo' => [ - 'min_length' => 'Shame, shame. Too short.', - ], - ], - ]; - - //-------------------------------------------------------------------- - - protected function setUp(): void - { - parent::setUp(); - $this->validation = new Validation((object)$this->config, \Config\Services::renderer()); - $this->validation->reset(); - - $_FILES = []; - } - - /** - * @group DatabaseLive - */ - public function testIsUniqueFalse() - { - $this->hasInDatabase('user', [ - 'name' => 'Derek', - 'email' => 'derek@world.com', - 'country' => 'USA', - ]); - - $data = [ - 'email' => 'derek@world.com', - ]; - - $this->validation->setRules([ - 'email' => 'is_unique[user.email]', - ]); - - $this->assertFalse($this->validation->run($data)); - } - - //-------------------------------------------------------------------- - - /** - * @group DatabaseLive - */ - public function testIsUniqueTrue() - { - $data = [ - 'email' => 'derek@world.co.uk', - ]; - - $this->validation->setRules([ - 'email' => 'is_unique[user.email]', - ]); - - $this->assertTrue($this->validation->run($data)); - } - - //-------------------------------------------------------------------- - - /** - * @group DatabaseLive - */ - public function testIsUniqueIgnoresParams() - { - $this->hasInDatabase('user', [ - 'name' => 'Derek', - 'email' => 'derek@world.co.uk', - 'country' => 'GB', - ]); - - $db = Database::connect(); - $row = $db->table('user') - ->limit(1) - ->get() - ->getRow(); - - $data = [ - 'email' => 'derek@world.co.uk', - ]; - - $this->validation->setRules([ - 'email' => "is_unique[user.email,id,{$row->id}]", - ]); - - $this->assertTrue($this->validation->run($data)); - } - - //-------------------------------------------------------------------- - - /** - * @group DatabaseLive - */ - public function testIsUniqueIgnoresParamsPlaceholders() - { - $this->hasInDatabase('user', [ - 'name' => 'Derek', - 'email' => 'derek@world.co.uk', - 'country' => 'GB', - ]); - - $db = Database::connect(); - $row = $db->table('user') - ->limit(1) - ->get() - ->getRow(); - - $data = [ - 'id' => $row->id, - 'email' => 'derek@world.co.uk', - ]; - - $this->validation->setRules([ - 'email' => "is_unique[user.email,id,{id}]", - ]); - - $this->assertTrue($this->validation->run($data)); - } - - //-------------------------------------------------------------------- -}