From e5e67ebed522dc390ac98c8c58fd1d6ada2dd2c4 Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 00:04:49 +0300 Subject: [PATCH 1/7] Add testValidateTargetClass for reproduce the bug. When IDs targetClass & model(not new) is same then unique validator passed --- tests/framework/validators/UniqueValidatorTest.php | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/framework/validators/UniqueValidatorTest.php b/tests/framework/validators/UniqueValidatorTest.php index 7a1b805..09e7b6f 100644 --- a/tests/framework/validators/UniqueValidatorTest.php +++ b/tests/framework/validators/UniqueValidatorTest.php @@ -5,6 +5,8 @@ namespace yiiunit\framework\validators; use yii\validators\UniqueValidator; use Yii; use yiiunit\data\ar\ActiveRecord; +use yiiunit\data\ar\Category; +use yiiunit\data\ar\Item; use yiiunit\data\ar\Order; use yiiunit\data\ar\OrderItem; use yiiunit\data\validators\models\FakedValidationModel; @@ -136,4 +138,28 @@ class UniqueValidatorTest extends DatabaseTestCase $val->validateAttribute($m, 'id'); $this->assertFalse($m->hasErrors('id')); } + + public function testValidateTargetClass() + { + $val = new UniqueValidator([ + 'targetClass' => Category::className(), + 'targetAttribute' => ['name'], + ]); + + /** @var Item $m */ + $m = Item::findOne(1); + $this->assertEquals('Agile Web Application Development with Yii1.1 and PHP5', $m->name); + $val->validateAttribute($m, 'name'); + $this->assertFalse($m->hasErrors('name')); + + $m->name = 'Movies'; //as INSERT INTO `category` (name) VALUES ('Movies'); + $val->validateAttribute($m, 'name'); + $this->assertTrue($m->hasErrors('name')); + $m->clearErrors('name'); + + // ID Item equal ID Category + $m->name = 'Books'; //as INSERT INTO `category` (name) VALUES ('Books'); + $val->validateAttribute($m, 'name'); + $this->assertTrue($m->hasErrors('name')); + } } From f0532b8818b8bddb2d34d351c87e60ee9c8b59fb Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 00:07:20 +0300 Subject: [PATCH 2/7] Fix https://github.com/yiisoft/yii2/pull/10263 --- framework/validators/UniqueValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/validators/UniqueValidator.php b/framework/validators/UniqueValidator.php index 19882c6..68903ab 100644 --- a/framework/validators/UniqueValidator.php +++ b/framework/validators/UniqueValidator.php @@ -106,7 +106,7 @@ class UniqueValidator extends Validator $query->andWhere($this->filter); } - if (!$model instanceof ActiveRecordInterface || $model->getIsNewRecord()) { + if (!$model instanceof ActiveRecordInterface || $model->getIsNewRecord() || $model::className() !== $targetClass) { // if current $model isn't in the database yet then it's OK just to call exists() $exists = $query->exists(); } else { From 9cc6f7a4158c7d6b3f4d33436a2831f19370804e Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 18:07:45 +0300 Subject: [PATCH 3/7] changelog has been added --- framework/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index f0ece02..aa27ced 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -3,7 +3,7 @@ Yii Framework 2 Change Log 2.0.7 under development ----------------------- - +- Bug #10263: Unique validator passed for update-scenario when IDs targetClass and model is same (bupy7, githubjeka) - Bug #6351: Find MySQL FK constraints from `information_schema` tables instead of `SHOW CREATE TABLE` to improve reliability (nineinchnick) - Bug #6363, #8301, #8582, #9566: Fixed data methods and PJAX issues when used together (derekisbusy) - Bug #6876: Fixed RBAC migration MSSQL cascade problem (thejahweh) From 60081cbd47a11e4110a12323761e23a797187416 Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 18:33:09 +0300 Subject: [PATCH 4/7] updated CHANGELOG --- framework/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index aa27ced..461bad1 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -3,7 +3,6 @@ Yii Framework 2 Change Log 2.0.7 under development ----------------------- -- Bug #10263: Unique validator passed for update-scenario when IDs targetClass and model is same (bupy7, githubjeka) - Bug #6351: Find MySQL FK constraints from `information_schema` tables instead of `SHOW CREATE TABLE` to improve reliability (nineinchnick) - Bug #6363, #8301, #8582, #9566: Fixed data methods and PJAX issues when used together (derekisbusy) - Bug #6876: Fixed RBAC migration MSSQL cascade problem (thejahweh) @@ -36,6 +35,7 @@ Yii Framework 2 Change Log - Bug #10029: Fixed MaskedInput not working with PJAX (martrix78, samdark) - Bug #10101: Fixed assignments saving on role removing in `\yii\rbac\PhpManager` (rezident1307) - Bug #10142: Fixed `yii\validators\EmailValidator` to check the length of email properly (silverfire) +- Bug #10263: Unique validator passed for update-scenario when IDs targetClass and model is same (bupy7, githubjeka) - Bug: Fixed generation of canonical URLs for `ViewAction` pages (samdark) - Bug: Fixed `mb_*` functions calls to use `UTF-8` or `Yii::$app->charset` (silverfire) - Enh #3506: Added `\yii\validators\IpValidator` to perform validation of IP addresses and subnets (SilverFire, samdark) From fd6e33ccf39cf6e1fafa72311ba63d3d621693fa Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 19:32:03 +0300 Subject: [PATCH 5/7] Semantics of the test has been improved --- tests/framework/validators/UniqueValidatorTest.php | 40 +++++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/tests/framework/validators/UniqueValidatorTest.php b/tests/framework/validators/UniqueValidatorTest.php index 09e7b6f..8229a46 100644 --- a/tests/framework/validators/UniqueValidatorTest.php +++ b/tests/framework/validators/UniqueValidatorTest.php @@ -6,9 +6,11 @@ use yii\validators\UniqueValidator; use Yii; use yiiunit\data\ar\ActiveRecord; use yiiunit\data\ar\Category; +use yiiunit\data\ar\Customer; use yiiunit\data\ar\Item; use yiiunit\data\ar\Order; use yiiunit\data\ar\OrderItem; +use yiiunit\data\ar\Profile; use yiiunit\data\validators\models\FakedValidationModel; use yiiunit\data\validators\models\ValidatorTestMainModel; use yiiunit\data\validators\models\ValidatorTestRefModel; @@ -141,25 +143,29 @@ class UniqueValidatorTest extends DatabaseTestCase public function testValidateTargetClass() { + // Expect to "Description" and "address" isn't equals $val = new UniqueValidator([ - 'targetClass' => Category::className(), - 'targetAttribute' => ['name'], + 'targetClass' => Customer::className(), + 'targetAttribute' => ['description'=>'address'], ]); - /** @var Item $m */ - $m = Item::findOne(1); - $this->assertEquals('Agile Web Application Development with Yii1.1 and PHP5', $m->name); - $val->validateAttribute($m, 'name'); - $this->assertFalse($m->hasErrors('name')); - - $m->name = 'Movies'; //as INSERT INTO `category` (name) VALUES ('Movies'); - $val->validateAttribute($m, 'name'); - $this->assertTrue($m->hasErrors('name')); - $m->clearErrors('name'); - - // ID Item equal ID Category - $m->name = 'Books'; //as INSERT INTO `category` (name) VALUES ('Books'); - $val->validateAttribute($m, 'name'); - $this->assertTrue($m->hasErrors('name')); + /** @var Profile $m */ + $m = Profile::findOne(1); + $this->assertEquals('profile customer 1', $m->description); + $val->validateAttribute($m, 'description'); + $this->assertFalse($m->hasErrors('description')); + + // ID Profile not equal ID Customer + // (1, description = address2) <=> (2,address = address2) + $m->description = 'address2'; + $val->validateAttribute($m, 'description'); + $this->assertTrue($m->hasErrors('description')); + $m->clearErrors('description'); + + // ID Profile(1) equal ID Customer(1) + // (1, description = address1) <=> (1,address = address1) BUG #10263 + $m->description = 'address1'; + $val->validateAttribute($m, 'description'); + $this->assertTrue($m->hasErrors('description')); } } From 0fc744598df847a859dd4188c1600c86e287a3cd Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 19:43:29 +0300 Subject: [PATCH 6/7] optimized imports & add phpDoc --- tests/framework/validators/UniqueValidatorTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/framework/validators/UniqueValidatorTest.php b/tests/framework/validators/UniqueValidatorTest.php index 8229a46..026cbad 100644 --- a/tests/framework/validators/UniqueValidatorTest.php +++ b/tests/framework/validators/UniqueValidatorTest.php @@ -5,9 +5,7 @@ namespace yiiunit\framework\validators; use yii\validators\UniqueValidator; use Yii; use yiiunit\data\ar\ActiveRecord; -use yiiunit\data\ar\Category; use yiiunit\data\ar\Customer; -use yiiunit\data\ar\Item; use yiiunit\data\ar\Order; use yiiunit\data\ar\OrderItem; use yiiunit\data\ar\Profile; @@ -42,6 +40,7 @@ class UniqueValidatorTest extends DatabaseTestCase $m = ValidatorTestMainModel::find()->one(); $val->validateAttribute($m, 'id'); $this->assertFalse($m->hasErrors('id')); + /** @var ValidatorTestRefModel $m */ $m = ValidatorTestRefModel::findOne(1); $val->validateAttribute($m, 'ref'); $this->assertTrue($m->hasErrors('ref')); @@ -77,6 +76,7 @@ class UniqueValidatorTest extends DatabaseTestCase public function testValidateNonDatabaseAttribute() { $val = new UniqueValidator(['targetClass' => ValidatorTestRefModel::className(), 'targetAttribute' => 'ref']); + /** @var ValidatorTestMainModel $m */ $m = ValidatorTestMainModel::findOne(1); $val->validateAttribute($m, 'testMainVal'); $this->assertFalse($m->hasErrors('testMainVal')); @@ -101,6 +101,7 @@ class UniqueValidatorTest extends DatabaseTestCase 'targetAttribute' => ['order_id', 'item_id'], ]); // validate old record + /** @var ValidatorTestMainModel $m */ $m = OrderItem::findOne(['order_id' => 1, 'item_id' => 2]); $val->validateAttribute($m, 'order_id'); $this->assertFalse($m->hasErrors('order_id')); @@ -121,6 +122,7 @@ class UniqueValidatorTest extends DatabaseTestCase 'targetAttribute' => ['id' => 'order_id'], ]); // validate old record + /** @var Order $m */ $m = Order::findOne(1); $val->validateAttribute($m, 'id'); $this->assertTrue($m->hasErrors('id')); From a215013f68d72e69cf17656de297753dbfc302d2 Mon Sep 17 00:00:00 2001 From: githubjeka Date: Fri, 27 Nov 2015 19:48:20 +0300 Subject: [PATCH 7/7] Missing phpDoc properties has been added --- tests/data/validators/models/ValidatorTestRefModel.php | 5 +++++ tests/framework/validators/UniqueValidatorTest.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/data/validators/models/ValidatorTestRefModel.php b/tests/data/validators/models/ValidatorTestRefModel.php index bf0ebe5..bd70734 100644 --- a/tests/data/validators/models/ValidatorTestRefModel.php +++ b/tests/data/validators/models/ValidatorTestRefModel.php @@ -4,6 +4,11 @@ namespace yiiunit\data\validators\models; use yiiunit\data\ar\ActiveRecord; +/** + * @property int id + * @property string a_field + * @property int ref + */ class ValidatorTestRefModel extends ActiveRecord { diff --git a/tests/framework/validators/UniqueValidatorTest.php b/tests/framework/validators/UniqueValidatorTest.php index 026cbad..1a8708b 100644 --- a/tests/framework/validators/UniqueValidatorTest.php +++ b/tests/framework/validators/UniqueValidatorTest.php @@ -101,7 +101,7 @@ class UniqueValidatorTest extends DatabaseTestCase 'targetAttribute' => ['order_id', 'item_id'], ]); // validate old record - /** @var ValidatorTestMainModel $m */ + /** @var OrderItem $m */ $m = OrderItem::findOne(['order_id' => 1, 'item_id' => 2]); $val->validateAttribute($m, 'order_id'); $this->assertFalse($m->hasErrors('order_id'));