Подрефакторена форма отправки нового письма с активацией аккаунта, дописаны юнит и функциональные тесты

This commit is contained in:
ErickSkrauch
2016-03-13 21:24:49 +03:00
parent b9ee667829
commit 7343a3b506
10 changed files with 238 additions and 48 deletions

View File

@@ -2,7 +2,7 @@
namespace api\controllers;
use api\models\ConfirmEmailForm;
use api\models\NewAccountActivationForm;
use api\models\RepeatAccountActivationForm;
use api\models\RegistrationForm;
use Yii;
use yii\filters\AccessControl;
@@ -13,13 +13,13 @@ class SignupController extends Controller {
public function behaviors() {
return ArrayHelper::merge(parent::behaviors(), [
'authenticator' => [
'except' => ['index', 'new-message', 'confirm'],
'except' => ['index', 'repeat-message', 'confirm'],
],
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'actions' => ['index', 'new-message', 'confirm'],
'actions' => ['index', 'repeat-message', 'confirm'],
'allow' => true,
'roles' => ['?'],
],
@@ -51,10 +51,10 @@ class SignupController extends Controller {
];
}
public function actionNewMessage() {
$model = new NewAccountActivationForm();
public function actionRepeatMessage() {
$model = new RepeatAccountActivationForm();
$model->load(Yii::$app->request->post());
if (!$model->sendNewMessage()) {
if (!$model->sendRepeatMessage()) {
$response = [
'success' => false,
'errors' => $this->normalizeModelErrors($model->getErrors()),
@@ -63,8 +63,8 @@ class SignupController extends Controller {
if ($response['errors']['email'] === 'error.recently_sent_message') {
$activeActivation = $model->getActiveActivation();
$response['data'] = [
'can_repeat_in' => $activeActivation->created_at - time() + NewAccountActivationForm::REPEAT_FREQUENCY,
'repeat_frequency' => NewAccountActivationForm::REPEAT_FREQUENCY,
'canRepeatIn' => $activeActivation->created_at - time() + RepeatAccountActivationForm::REPEAT_FREQUENCY,
'repeatFrequency' => RepeatAccountActivationForm::REPEAT_FREQUENCY,
];
}

View File

@@ -0,0 +1,6 @@
<?php
namespace api\exceptions;
class Exception extends \Exception {
}

View File

@@ -0,0 +1,11 @@
<?php
namespace api\exceptions;
/**
* Исключение можно использовать для тех кейсов, где вроде указанных исход не продполагается,
* но теоретически может произойти. Целью является отлавливание таких участков и доработка логики,
* если такие ситуации всё же будут иметь место случаться.
*/
class ThisShouldNotHaveHappenedException extends Exception {
}

View File

@@ -7,7 +7,7 @@ use common\models\EmailActivation;
use Yii;
use yii\base\ErrorException;
class NewAccountActivationForm extends BaseApiForm {
class RepeatAccountActivationForm extends BaseApiForm {
// Частота повтора отправки нового письма
const REPEAT_FREQUENCY = 5 * 60;
@@ -18,18 +18,21 @@ class NewAccountActivationForm extends BaseApiForm {
return [
['email', 'filter', 'filter' => 'trim'],
['email', 'required', 'message' => 'error.email_required'],
['email', 'validateAccountForEmail'],
['email', 'validateEmailForAccount'],
['email', 'validateExistsActivation'],
];
}
public function validateAccountForEmail($attribute) {
public function validateEmailForAccount($attribute) {
if (!$this->hasErrors($attribute)) {
$account = $this->getAccount();
if ($account && $account->status === Account::STATUS_ACTIVE) {
$this->addError($attribute, "error.account_already_activated");
} elseif (!$account) {
if ($account === null) {
$this->addError($attribute, "error.{$attribute}_not_found");
} elseif ($account->status === Account::STATUS_ACTIVE) {
$this->addError($attribute, "error.account_already_activated");
} elseif ($account->status !== Account::STATUS_REGISTERED) {
// TODO: такие аккаунты следует логировать за попытку к саботажу
$this->addError($attribute, "error.account_cannot_resend_message");
}
}
}
@@ -42,7 +45,7 @@ class NewAccountActivationForm extends BaseApiForm {
}
}
public function sendNewMessage() {
public function sendRepeatMessage() {
if (!$this->validate()) {
return false;
}
@@ -50,15 +53,10 @@ class NewAccountActivationForm extends BaseApiForm {
$account = $this->getAccount();
$transaction = Yii::$app->db->beginTransaction();
try {
// Удаляем все активации аккаунта для пользователя этого E-mail адреса
/** @var EmailActivation[] $activations */
$activations = $account->getEmailActivations()
->andWhere(['type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION])
->all();
foreach ($activations as $activation) {
$activation->delete();
}
EmailActivation::deleteAll([
'account_id' => $account->id,
'type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION,
]);
$activation = new EmailActivation();
$activation->account_id = $account->id;