From b277f48785de8e5051d618a94edc0c5c747dd3fd Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sun, 20 Mar 2016 23:33:09 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B5=D1=84=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D1=84=D0=BE=D1=80=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/models/ChangePasswordForm.php | 40 +++--- api/models/LoginForm.php | 7 +- .../unit/models/ChangePasswordFormTest.php | 68 +++------ .../api/unit/models/ConfirmEmailFormTest.php | 5 +- .../api/unit/models/LoginFormTest.php | 136 ++++++++++++------ .../common/_support/FixtureHelper.php | 5 +- 6 files changed, 137 insertions(+), 124 deletions(-) diff --git a/api/models/ChangePasswordForm.php b/api/models/ChangePasswordForm.php index b112f64..36bf256 100644 --- a/api/models/ChangePasswordForm.php +++ b/api/models/ChangePasswordForm.php @@ -2,12 +2,12 @@ namespace api\models; use api\models\base\ApiForm; +use api\models\base\PasswordProtectedForm; use common\models\Account; use Yii; +use yii\helpers\ArrayHelper; -class ChangePasswordForm extends ApiForm { - - public $password; +class ChangePasswordForm extends PasswordProtectedForm { public $newPassword; @@ -18,33 +18,16 @@ class ChangePasswordForm extends ApiForm { */ private $_account; - /** - * @param Account $account - * @param array $config - */ - public function __construct(Account $account, array $config = []) { - $this->_account = $account; - parent::__construct($config); - } - /** * @inheritdoc */ public function rules() { - return [ - ['password', 'required', 'message' => 'error.password_required'], + return ArrayHelper::merge(parent::rules(), [ ['newPassword', 'required', 'message' => 'error.newPassword_required'], ['newRePassword', 'required', 'message' => 'error.newRePassword_required'], - ['password', 'validatePassword'], ['newPassword', 'string', 'min' => 8, 'tooShort' => 'error.password_too_short'], ['newRePassword', 'validatePasswordAndRePasswordMatch'], - ]; - } - - public function validatePassword($attribute) { - if (!$this->hasErrors() && !$this->_account->validatePassword($this->$attribute)) { - $this->addError($attribute, 'error.' . $attribute . '_incorrect'); - } + ]); } public function validatePasswordAndRePasswordMatch($attribute) { @@ -69,4 +52,17 @@ class ChangePasswordForm extends ApiForm { return $account->save(); } + protected function getAccount() { + return $this->_account; + } + + /** + * @param Account $account + * @param array $config + */ + public function __construct(Account $account, array $config = []) { + $this->_account = $account; + parent::__construct($config); + } + } diff --git a/api/models/LoginForm.php b/api/models/LoginForm.php index 0d43056..2c7ef1d 100644 --- a/api/models/LoginForm.php +++ b/api/models/LoginForm.php @@ -71,11 +71,14 @@ class LoginForm extends ApiForm { */ public function getAccount() { if ($this->_account === NULL) { - $attribute = strpos($this->login, '@') ? 'email' : 'username'; - $this->_account = Account::findOne([$attribute => $this->login]); + $this->_account = Account::findOne([$this->getLoginAttribute() => $this->login]); } return $this->_account; } + public function getLoginAttribute() { + return strpos($this->login, '@') ? 'email' : 'username'; + } + } diff --git a/tests/codeception/api/unit/models/ChangePasswordFormTest.php b/tests/codeception/api/unit/models/ChangePasswordFormTest.php index bf777b7..18c6c4a 100644 --- a/tests/codeception/api/unit/models/ChangePasswordFormTest.php +++ b/tests/codeception/api/unit/models/ChangePasswordFormTest.php @@ -23,57 +23,29 @@ class ChangePasswordFormTest extends DbTestCase { ]; } - public function testChangePasswordErrors() { - /** @var Account $account */ - $account = Account::findOne($this->accounts['admin']['id']); - $model = new ChangePasswordForm($account); - $this->specify('expected error.{field}_required if we don\'t pass some fields', function() use ($model, $account) { - expect('form should return false', $model->changePassword())->false(); - expect('form should contain errors', $model->getErrors())->equals([ - 'password' => ['error.password_required'], - 'newPassword' => ['error.newPassword_required'], - 'newRePassword' => ['error.newRePassword_required'], + public function testValidatePasswordAndRePasswordMatch() { + $this->specify('error.newRePassword_does_not_match expected if passwords not match', function() { + $account = new Account(); + $account->setPassword('12345678'); + $model = new ChangePasswordForm($account, [ + 'password' => '12345678', + 'newPassword' => 'my-new-password', + 'newRePassword' => 'another-password', ]); - expect('password not changed', $account->validatePassword('password_0'))->true(); + $model->validatePasswordAndRePasswordMatch('newRePassword'); + expect($model->getErrors('newRePassword'))->equals(['error.newRePassword_does_not_match']); }); - $model = new ChangePasswordForm($account, [ - 'password' => 'this-is-wrong-password', - 'newPassword' => 'my-new-password', - 'newRePassword' => 'my-new-password', - ]); - $this->specify('expected error.password_incorrect if we pass invalid current account password', function() use ($model, $account) { - expect('form should return false', $model->changePassword())->false(); - expect('form should contain errors', $model->getErrors())->equals([ - 'password' => ['error.password_incorrect'], + $this->specify('no errors expected if passwords are valid', function() { + $account = new Account(); + $account->setPassword('12345678'); + $model = new ChangePasswordForm($account, [ + 'password' => '12345678', + 'newPassword' => 'my-new-password', + 'newRePassword' => 'my-new-password', ]); - expect('password not changed', $account->validatePassword('password_0'))->true(); - }); - - $model = new ChangePasswordForm($account, [ - 'password' => 'password_0', - 'newPassword' => 'short', - 'newRePassword' => 'short', - ]); - $this->specify('expected error.password_too_short if we pass short password', function() use ($model, $account) { - expect('form should return false', $model->changePassword())->false(); - expect('form should contain errors', $model->getErrors())->equals([ - 'newPassword' => ['error.password_too_short'], - ]); - expect('password not changed', $account->validatePassword('password_0'))->true(); - }); - - $model = new ChangePasswordForm($account, [ - 'password' => 'password_0', - 'newPassword' => 'first-valid-pass', - 'newRePassword' => 'another-valid-pass', - ]); - $this->specify('expected error.newRePassword_does_not_match if we passwords mismatch', function() use ($model, $account) { - expect('form should return false', $model->changePassword())->false(); - expect('form should contain errors', $model->getErrors())->equals([ - 'newRePassword' => ['error.newRePassword_does_not_match'], - ]); - expect('password not changed', $account->validatePassword('password_0'))->true(); + $model->validatePasswordAndRePasswordMatch('newRePassword'); + expect($model->getErrors('newRePassword'))->isEmpty(); }); } @@ -88,7 +60,6 @@ class ChangePasswordFormTest extends DbTestCase { $this->specify('successfully change password with modern hash strategy', function() use ($model, $account) { expect('form should return true', $model->changePassword())->true(); expect('new password should be successfully stored into account', $account->validatePassword('my-new-password'))->true(); - expect('always use new strategy', $account->password_hash_strategy)->equals(Account::PASS_HASH_STRATEGY_YII2); }); /** @var Account $account */ @@ -101,7 +72,6 @@ class ChangePasswordFormTest extends DbTestCase { $this->specify('successfully change password with legacy hash strategy', function() use ($model, $account) { expect('form should return true', $model->changePassword())->true(); expect('new password should be successfully stored into account', $account->validatePassword('my-new-password'))->true(); - expect('strategy should be changed to modern', $account->password_hash_strategy)->equals(Account::PASS_HASH_STRATEGY_YII2); }); } diff --git a/tests/codeception/api/unit/models/ConfirmEmailFormTest.php b/tests/codeception/api/unit/models/ConfirmEmailFormTest.php index 92b9029..2c71720 100644 --- a/tests/codeception/api/unit/models/ConfirmEmailFormTest.php +++ b/tests/codeception/api/unit/models/ConfirmEmailFormTest.php @@ -30,12 +30,13 @@ class ConfirmEmailFormTest extends DbTestCase { ]); } - public function testValidInput() { + public function testConfirm() { $fixture = $this->emailActivations[0]; $model = $this->createModel($fixture['key']); $this->specify('expect true result', function() use ($model, $fixture) { expect('model return successful result', $model->confirm())->notEquals(false); - expect('email activation key is not exist', EmailActivation::find()->andWhere(['key' => $fixture['key']])->exists())->false(); + $activationExists = EmailActivation::find()->andWhere(['key' => $fixture['key']])->exists(); + expect('email activation key is not exist', $activationExists)->false(); /** @var Account $user */ $user = Account::findOne($fixture['account_id']); expect('user status changed to active', $user->status)->equals(Account::STATUS_ACTIVE); diff --git a/tests/codeception/api/unit/models/LoginFormTest.php b/tests/codeception/api/unit/models/LoginFormTest.php index bc9dc97..32b2061 100644 --- a/tests/codeception/api/unit/models/LoginFormTest.php +++ b/tests/codeception/api/unit/models/LoginFormTest.php @@ -3,69 +3,111 @@ namespace tests\codeception\api\models; use api\models\LoginForm; use Codeception\Specify; +use common\models\Account; use tests\codeception\api\unit\DbTestCase; -use tests\codeception\common\fixtures\AccountFixture; use Yii; -/** - * @property array $accounts - */ class LoginFormTest extends DbTestCase { use Specify; - protected function tearDown() { - Yii::$app->user->logout(); - parent::tearDown(); - } - - public function fixtures() { - return [ - 'accounts' => [ - 'class' => AccountFixture::class, - 'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php', - ], - ]; - } - - protected function createModel($login = '', $password = '') { - return new LoginForm([ - 'login' => $login, - 'password' => $password, - ]); - } - - public function testIncorrectLogin() { - $model = $this->createModel('not-esist-login', 'fully-invalid-password'); - $this->specify('get errors and don\'t log in into account with wrong credentials', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('error messages should be set', $model->errors)->notEmpty(); - }); - - $model = $this->createModel($this->accounts['not-activated-account']['username'], 'password_0'); - $this->specify('get error if account data valid, but account is not activated', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('error messages should be set', $model->errors)->equals([ - 'login' => [ - 'error.account_not_activated', - ], + public function testValidateLogin() { + $this->specify('error.login_not_exist if login not exists', function() { + $model = new DummyLoginForm([ + 'login' => 'mr-test', + 'account' => null, ]); + $model->validateLogin('login'); + expect($model->getErrors('login'))->equals(['error.login_not_exist']); + }); + + $this->specify('no errors if login exists', function() { + $model = new DummyLoginForm([ + 'login' => 'mr-test', + 'account' => new Account(), + ]); + $model->validateLogin('login'); + expect($model->getErrors('login'))->isEmpty(); }); } - public function testLoginByUsernameCorrect() { - $model = $this->createModel($this->accounts['admin']['username'], 'password_0'); - $this->specify('user should be able to login with correct username and password', function () use ($model) { + public function testValidatePassword() { + $this->specify('error.password_incorrect if password invalid', function() { + $model = new DummyLoginForm([ + 'password' => '87654321', + 'account' => new Account(['password' => '12345678']), + ]); + $model->validatePassword('password'); + expect($model->getErrors('password'))->equals(['error.password_incorrect']); + }); + + $this->specify('no errors if password valid', function() { + $model = new DummyLoginForm([ + 'password' => '12345678', + 'account' => new Account(['password' => '12345678']), + ]); + $model->validatePassword('password'); + expect($model->getErrors('password'))->isEmpty(); + }); + } + + public function testValidateActivity() { + $this->specify('error.account_not_activated if account in not activated state', function() { + $model = new DummyLoginForm([ + 'account' => new Account(['status' => Account::STATUS_REGISTERED]), + ]); + $model->validateActivity('login'); + expect($model->getErrors('login'))->equals(['error.account_not_activated']); + }); + + $this->specify('no errors if account active', function() { + $model = new DummyLoginForm([ + 'account' => new Account(['status' => Account::STATUS_ACTIVE]), + ]); + $model->validateActivity('login'); + expect($model->getErrors('login'))->isEmpty(); + }); + } + + public function testLogin() { + $this->specify('user should be able to login with correct username and password', function () { + $model = new DummyLoginForm([ + 'login' => 'erickskrauch', + 'password' => '12345678', + 'account' => new Account([ + 'username' => 'erickskrauch', + 'password' => '12345678', + 'status' => Account::STATUS_ACTIVE, + ]), + ]); expect('model should login user', $model->login())->notEquals(false); expect('error message should not be set', $model->errors)->isEmpty(); }); } - public function testLoginByEmailCorrect() { - $model = $this->createModel($this->accounts['admin']['email'], 'password_0'); - $this->specify('user should be able to login with correct email and password', function () use ($model) { - expect('model should login user', $model->login())->notEquals(false); - expect('error message should not be set', $model->errors)->isEmpty(); + public function testGetLoginAttribute() { + $this->specify('email if login look like email value', function() { + $model = new DummyLoginForm(['login' => 'erickskrauch@ely.by']); + expect($model->getLoginAttribute())->equals('email'); + }); + + $this->specify('username in any other case', function() { + $model = new DummyLoginForm(['login' => 'erickskrauch']); + expect($model->getLoginAttribute())->equals('username'); }); } } + +class DummyLoginForm extends LoginForm { + + private $_account; + + public function setAccount($value) { + $this->_account = $value; + } + + public function getAccount() { + return $this->_account; + } + +} diff --git a/tests/codeception/common/_support/FixtureHelper.php b/tests/codeception/common/_support/FixtureHelper.php index c413a84..b3a336b 100644 --- a/tests/codeception/common/_support/FixtureHelper.php +++ b/tests/codeception/common/_support/FixtureHelper.php @@ -2,6 +2,7 @@ namespace tests\codeception\common\_support; use Codeception\Module; +use Codeception\TestCase; use tests\codeception\common\fixtures\AccountFixture; use tests\codeception\common\fixtures\EmailActivationFixture; use tests\codeception\common\fixtures\OauthClientFixture; @@ -29,11 +30,11 @@ class FixtureHelper extends Module { getFixture as protected; } - public function _beforeSuite($settings = []) { + public function _before(TestCase $test) { $this->loadFixtures(); } - public function _afterSuite() { + public function _after(TestCase $test) { $this->unloadFixtures(); }