Completed
Push — master ( b61081...bf01ff )
by Pavel
04:03
created

UserTest::testRegistration()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 116
Code Lines 89

Duplication

Lines 7
Ratio 6.03 %

Importance

Changes 0
Metric Value
dl 7
loc 116
c 0
b 0
f 0
rs 8.2857
cc 1
eloc 89
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace tests\codeception;
4
5
use Codeception\Lib\Connector\Yii2\TestMailer;
6
use Codeception\Specify;
7
use inblank\activeuser\models\Profile;
8
use inblank\activeuser\models\User;
9
use inblank\activeuser\Module;
10
use tests\codeception\_fixtures\ProfileFixture;
11
use tests\codeception\_fixtures\UserFixture;
12
use yii;
13
14
/**
15
 * @property \UnitTester $tester
16
 */
17
class UserTest extends \Codeception\Test\Unit
18
{
19
    use Specify {
20
        specify as parentSpecify;
21
    }
22
23
    /** @var  Module */
24
    public $module;
25
26
    /**
27
     * Registration test with `null` data for User model
28
     */
29
    public function testRegistrationNull()
30
    {
31
        $this->module->enableRegistration = true;
32
        $this->module->enableConfirmation = true;
33
        $this->module->registrationFields = [];
34
35
        $this->specify("we have register with null data", function () {
36
            $user = new User([
37
                'status' => null,
38
                'email' => '[email protected]',
39
                'pass_hash' => null,
40
                'name' => null,
41
                'gender' => null,
42
                'birth' => null,
43
                'avatar' => null,
44
                'access_token' => null,
45
                'auth_key' => null,
46
                'token' => null,
47
                'token_created_at' => null,
48
                'registered_at' => null,
49
            ]);
50
            expect("we can register user with correct email and null data", $user->register())->true();
51
        });
52
    }
53
54
    /**
55
     * Creation test for User model
56
     */
57
    public function testCreation()
58
    {
59
        $this->module->enableRegistration = false;
60
61
        $this->specify("we have create user if registration disabled", function () {
62
            $user = new User([
63
                'email' => '[email protected]',
64
                'password' => 'password',
65
                'name' => 'Test user',
66
            ]);
67
            expect("we can create user if registration disabled", $user->create())->true();
68
            $this->tester->dontSeeEmailIsSent();
69
            //create() on existing user throw \RuntimeException
70
            $user->create();
71
        }, ['throws' => new \RuntimeException]);
72
73
        $this->module->enableRegistration = true;
74
        $this->specify("we have create user with register email", function () {
75
            $user = new User([
76
                'email' => '[email protected]',
77
                'password' => 'password',
78
                'name' => 'Test user 2',
79
            ]);
80
            expect("we can create user if registration disabled", $user->create(true))->true();
81
            /** @var TestMailer $message */
82
            /** @var yii\swiftmailer\Message $message */
83
            $this->tester->seeEmailIsSent();
84
            $message = $this->tester->grabLastSentEmail();
85
            expect("we must see email", $message)->notNull();
86
            expect("we must see email to user", $message->getTo())->hasKey($user->email);
87
            expect("we must see registration email", $message->getSubject())->contains('register');
88
        });
89
90
        $this->specify("we have create user wit autogenerated password", function () {
91
            $user = new User([
92
                'email' => '[email protected]',
93
                'name' => 'Test user',
94
            ]);
95
            expect("we can create user with autogenerated password", $user->create())->true();
96
        });
97
98 View Code Duplication
        $this->specify("we have create user without name", function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
            $user = new User([
100
                'email' => '[email protected]',
101
                'password' => 'password',
102
            ]);
103
            expect("we can't create user without name", $user->create())->false();
104
            expect("we can see error `name`", $user->getErrors())->hasKey('name');
105
        });
106
    }
107
108
    /**
109
     * Blocking test for User model
110
     */
111
    public function testBlocking()
112
    {
113
        $this->module->enableBlockingEmail = true;
114
115
        $this->specify("we have block user", function () {
116
            /** @var User $user */
117
            //$user = $this->getFixture('user')->getModel('active');
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
118
            $user = $this->tester->grabFixture('users', 'active');
119
            expect("we can block user", $user->block())->true();
120
            $this->tester->seeEmailIsSent();
121
        });
122
123
        $this->specify("we have block already blocked user", function () {
124
            /** @var User $user */
125
            $user = $this->tester->grabFixture('users', 'blocked');
126
            expect("we can't block already blocked user", $user->block())->false();
127
        });
128
129
        $this->specify("we have block unconfirmed user", function () {
130
            /** @var User $user */
131
            $user = $this->tester->grabFixture('users', 'unconfirmed');
132
            expect("we can't block unconfirmed user", $user->block())->false();
133
        });
134
135
        $this->module->enableUnblockingEmail = true;
136 View Code Duplication
        $this->specify("we have unblock blocked user", function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
137
            /** @var User $user */
138
            $user = $this->tester->grabFixture('users', 'blocked');
139
            expect("we can unblock blocked user", $user->unblock())->true();
140
            $this->tester->seeEmailIsSent();
141
        });
142
143 View Code Duplication
        $this->specify("we have unblock not blocked user", function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
            /** @var User $user */
145
            $user = $this->tester->grabFixture('users', 'unconfirmed');
146
            expect("we can't unblock not blocked user", $user->unblock())->false();
147
            $this->tester->dontSeeEmailIsSent();
148
        });
149
150 View Code Duplication
        $this->specify("we have unblock user override mail setting", function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
            /** @var User $user */
152
            $user = $this->tester->grabFixture('users', 'active');
153
            expect("we can unblock user", $user->unblock(false))->true();
154
            $this->tester->dontSeeEmailIsSent();
155
        });
156
157 View Code Duplication
        $this->specify("we have block user override global email setting", function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
158
            /** @var User $user */
159
            $user = $this->tester->grabFixture('users', 'active');
160
            expect("we can block user", $user->block(false))->true();
161
            $this->tester->dontSeeEmailIsSent();
162
        });
163
    }
164
165
    /**
166
     * Registration test for User model
167
     */
168
    public function testRegistration()
169
    {
170
        $this->module->enableRegistration = false;
171
172
        $this->specify("we have register if registration disabled", function () {
173
            $user = new User([
174
                'email' => '[email protected]',
175
                'password' => 'password',
176
                'name' => 'Tester',
177
            ]);
178
            expect("we can't register if registration disabled", $user->register())->false();
179
            expect("we must see message about this", $user->getErrors())->hasKey('registration');
180
        });
181
182
        $this->module->enableRegistration = true;
183
        $this->module->enableConfirmation = true;
184
        $this->module->registrationFields = [];
185
        $this->specify("we have register user by email", function () {
186
            $user = new User([
187
                'email' => '[email protected]',
188
            ]);
189
            expect("we can register user by email only", $user->register())->true();
190
            expect("user must have register date", $user->registered_at)->notEmpty();
191
            expect("user must have status STATUS_CONFIRM", $user->status)->equals(User::STATUS_CONFIRM);
192
            expect("we can get user profile", Profile::findOne(['user_id' => $user->id]))->notNull();
193
194
            $this->tester->seeEmailIsSent();
195
            $message = $this->tester->grabLastSentEmail();
196
            expect("we must view confirmation email", $message->getTo())->hasKey($user->email);
197
            expect("we must view confirmation email", $message->getSubject())->contains('confirm');
198
199
            //register() on existing user throw \RuntimeException
200
            $user->register();
201
        }, ['throws' => new \RuntimeException]);
202
203 View Code Duplication
        $this->specify("we have register user with same email", function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
            $user = new User([
205
                'email' => '[email protected]',
206
            ]);
207
            expect("we can't create user with same email", $user->register())->false();
208
            expect("we must see error message", $user->getErrors())->hasKey('email');
209
        });
210
211
        $this->module->registrationFields = ['password'];
212
        $this->specify("we have register user by email with password", function () {
213
            $pass = 'password';
214
            $user = new User([
215
                'email' => '[email protected]',
216
            ]);
217
            expect("we can't register user without pass", $user->register())->false();
218
            expect('we must see error in password', $user->getErrors())->hasKey('password');
219
            $user->password = $pass;
220
            expect("we can register user", $user->register())->true();
221
            expect("`pass_hash` must match", Yii::$app->security->validatePassword($pass, $user->pass_hash))->true();
222
            expect("we can get user profile", Profile::findOne(['user_id' => $user->id]))->notNull();
223
        });
224
225
        $this->module->registrationFields = ['password', 'name'];
226
        $this->specify("we have register user with full data", function () {
227
            $pass = 'password';
228
            $name = 'Tester';
229
            $user = new User([
230
                'email' => '[email protected]',
231
            ]);
232
            expect("we can't register user without pass and name", $user->register())->false();
233
            expect('we must see error in password', $user->getErrors())->hasKey('password');
234
            expect('we must see error in name', $user->getErrors())->hasKey('name');
235
            $user->password = $pass;
236
            $user->name = $name;
237
            expect("we can register user", $user->register())->true();
238
            expect("`pass_hash` must match", Yii::$app->security->validatePassword($pass, $user->pass_hash))->true();
239
            expect("we can get user profile", Profile::findOne(['user_id' => $user->id]))->notNull();
240
            $user1 = User::findOne($user->id);
241
            expect("name must be set", $user1->name)->equals($name);
242
        });
243
244
        $this->module->registrationFields = ['password', 'name', 'gender', 'birth'];
245
        $this->specify("we have register user with full data", function () {
246
            $pass = 'password';
247
            $name = 'Tester';
248
            $gender = User::MALE;
249
            $birth = '2000-01-01';
250
            $user = new User([
251
                'email' => '[email protected]',
252
                'password' => $pass,
253
                'name' => $name,
254
            ]);
255
            expect("we can register user without gender and birth", $user->register())->true();
256
257
            $user = new User([
258
                'email' => '[email protected]',
259
                'password' => $pass,
260
                'name' => $name,
261
                'gender' => $gender,
262
                'birth' => $birth,
263
            ]);
264
            expect("we can register user with full data", $user->register())->true();
265
            $user1 = User::findOne($user->id);
266
            expect('we must see gender', $user1->gender)->equals($gender);
267
            expect('we must see birth', $user1->birth)->equals($birth);
268
        });
269
270
        $this->module->enableConfirmation = false;
271
        $this->module->registrationFields = [];
272
        $this->specify("we have register user without confirm email", function () {
273
            $user = new User([
274
                'email' => '[email protected]',
275
            ]);
276
            expect("we can register user", $user->register())->true();
277
            expect("user must have status STATUS_ACTIVE", $user->status)->equals(User::STATUS_ACTIVE);
278
            $this->tester->seeEmailIsSent();
279
            $message = $this->tester->grabLastSentEmail();
280
            expect("we must view registration email", $message->getTo())->hasKey($user->email);
281
            expect("we must view registration email", $message->getSubject())->contains('register');
282
        });
283
    }
284
285
    public function testConfirm()
286
    {
287
        $this->module->enableRegistration = true;
288
        $this->module->enableConfirmation = true;
289
        $this->module->registrationFields = [];
290
291
        $this->specify("we have register and confirm user", function () {
292
            $user = new User([
293
                'email' => '[email protected]',
294
            ]);
295
296
            expect('we can register user', $user->register())->true();
297
            expect('we must see status STATUS_CONFIRM', $user->status)->equals(User::STATUS_CONFIRM);
298
299
            $confirmedUser = User::findByToken($user->token);
300
            expect('we can confirm user', $confirmedUser->confirm())->true();
301
            expect('confirm user must be equal registered user', $confirmedUser->id)->equals($user->id);
302
            $this->tester->seeEmailIsSent();
303
            $message = $this->tester->grabLastSentEmail();
304
            expect("we must view register email", $message->getTo())->hasKey($user->email);
305
            expect("we must view register email", $message->getSubject())->contains('register');
306
307
            expect('we cannot confirm already confirmed user', $confirmedUser->confirm())->false();
308
            expect('we must see error key `error`', $confirmedUser->getErrors())->hasKey('error');
309
        });
310
311
        $this->specify("we have register and try confirm user with expired token", function () {
312
            $user = new User([
313
                'email' => '[email protected]',
314
            ]);
315
            expect('we can register user', $user->register())->true();
316
            $user->updateAttributes([
317
                'token_created_at' => time() - 60 * 60 * 24 * 1000,
318
            ]);
319
            expect("we can't confirm user with expired token", $user->confirm())->false();
320
            expect('we must see error key `token`', $user->getErrors())->hasKey('token');
321
        });
322
    }
323
324
    public function testRestore()
325
    {
326
        $this->specify("we have register and confirm user", function () {
327
            /** @var Module $module */
328
            $module = Yii::$app->getModule('activeuser');
329
330
            $module->enableRegistration = true;
331
            $module->enableConfirmation = true;
332
            $module->registrationFields = [];
333
334
            $user = new User([
335
                'email' => '[email protected]',
336
            ]);
337
338
            expect('we can register user', $user->register())->true();
339
            expect('we cannot request restore on unconfirmed user', $user->restore())->false();
340
            expect('we must see `error` error', $user->getErrors())->hasKey('error');
341
            expect('we can confirm user', $user->confirm())->true();
342
343
            $module->enablePasswordRestore = false;
344
            expect("we can't request restore if disabled", $user->restore())->false();
345
            expect('we must see `error` error', $user->getErrors())->hasKey('error');
346
347
            $module->enablePasswordRestore = true;
348
            Yii::$app->mailer->reset();
349
            expect('we can request restore', $user->restore())->true();
350
351
            $module->generatePassOnRestore = false;
352
            $checkedUser = User::findOne($user->id);
353
            expect('user must have STATUS_RESTORE', $checkedUser->status)->equals(User::STATUS_RESTORE);
354
            expect('user must have not empty token', $checkedUser->token)->notEmpty();
355
            $this->tester->seeEmailIsSent();
356
            $message = $this->tester->grabLastSentEmail();
357
            expect("we must view restore email", $message->getTo())->hasKey($checkedUser->email);
358
            expect("we must view restore email", $message->getSubject())->contains('restore');
359
360
            expect("we cannot change password on empty", $checkedUser->changePassword())->false();
361
            expect('we must see `password` error', $checkedUser->getErrors())->hasKey('password');
362
363
            $checkedUser->updateAttributes([
364
                'token_created_at' => time() - 60 * 60 * 24 * 1000,
365
            ]);
366
            expect("we can't change password user with expired token", $checkedUser->changePassword())->false();
367
            expect('we must see error key `token`', $checkedUser->getErrors())->hasKey('token');
368
            $checkedUser->updateAttributes([
369
                'token_created_at' => time() - 60,
370
            ]);
371
372
            $module->generatePassOnRestore = true;
373
            $checkedUser->password = '';
374
            Yii::$app->mailer->reset();
375
            expect("we can change password by automatically generated", $checkedUser->changePassword())->true();
376
            $password = $checkedUser->password;
377
            $user = User::findOne($checkedUser->id);
378
            expect('user must have STATUS_ACTIVE', $user->status)->equals(User::STATUS_ACTIVE);
379
            expect('token must be empty', $user->token)->isEmpty();
380
            expect('password must be changed and equal', Yii::$app->security->validatePassword($password, $user->pass_hash))->true();
381
            $this->tester->seeEmailIsSent();
382
            $message = $this->tester->grabLastSentEmail();
383
            expect("we must view change confirmation email", $message->getTo())->hasKey($user->email);
384
            expect("we must view change confirmation email", $message->getSubject())->contains('changed');
385
386
            // test manually changed password
387
            $user->restore();
388
            $checkedUser = User::findOne($user->id);
389
            $module->generatePassOnRestore = true;
390
            $password = 'qwerty';
391
            $checkedUser->password = $password;
392
            expect("we can change password on manually entered if set autogeneration", $checkedUser->changePassword())->true();
393
            expect('password must be changed and equal', Yii::$app->security->validatePassword($password, $checkedUser->pass_hash))->true();
394
395
            $checkedUser->restore();
396
            $user = User::findOne($checkedUser->id);
397
            $module->generatePassOnRestore = false;
398
            $password = '123456';
399
            $user->password = $password;
400
            expect("we can change password on manually entered if NOT set autogenerate", $user->changePassword())->true();
401
            expect('password must be changed and equal', Yii::$app->security->validatePassword($password, $user->pass_hash))->true();
402
403
            /** @var User $user */
404
            $user = $this->tester->grabFixture('users', 'active');
405
            expect("we can't change password if user not restore", $user->changePassword())->false();
406
            expect('we must see `error` error', $user->getErrors())->hasKey('error');
407
        });
408
409
        $this->specify("try to restore blocked user", function () {
410
            $user = User::findOne(['status' => User::STATUS_BLOCKED]);
411
            expect("we must have blocked user", $user)->notNull();
412
            expect("we cannot restore on blocked user", $user->restore())->false();
413
            expect('we must see `error`', $user->getErrors())->hasKey('error');
414
        });
415
    }
416
417
    public function testChecks()
418
    {
419
        /** @var User $user */
420
        $user = $this->tester->grabFixture('users', 'blocked');
421
        expect('user must be blocked', $user->isBlocked())->true();
422
        expect("user can't be active", $user->isActive())->false();
423
        expect("user can be confirmed", $user->isConfirmed())->true();
424
        expect("user can't be restored", $user->isRestore())->false();
425
426
        $user = $this->tester->grabFixture('users', 'unconfirmed');
427
        expect('user must be not confirmed', $user->isConfirmed())->false();
428
        expect("user can't be blocked", $user->isBlocked())->false();
429
        expect("user can't be active", $user->isActive())->false();
430
        expect("user can't be restored", $user->isRestore())->false();
431
432
        $user = $this->tester->grabFixture('users', 'active');
433
        expect('user must be active', $user->isActive())->true();
434
        expect("user can't be blocked", $user->isBlocked())->false();
435
        expect("user can be confirmed", $user->isConfirmed())->true();
436
        expect("user can't be restored", $user->isRestore())->false();
437
438
        $user = $this->tester->grabFixture('users', 'restore');
439
        expect('user must be restore', $user->isRestore())->true();
440
        expect("user can't be active", $user->isActive())->false();
441
        expect("user can't be blocked", $user->isBlocked())->false();
442
        expect("user can be confirmed", $user->isConfirmed())->true();
443
    }
444
445
    public function testGettersFinders()
446
    {
447
        /** @var User $user */
448
        $user = $this->tester->grabFixture('users', 'active');
449
        $accessTokens = ['active' => $user->access_token];
450
        expect("id getter must be equals direct access", $user->getId())->equals($user->id);
451
        expect("auth_key getter must be equals direct access", $user->getAuthKey())->equals($user->auth_key);
452
453
        expect("wrong auth_key cannot be tested", $user->validateAuthKey('wrong_key'))->false();
454
        expect("empty auth_key cannot be tested", $user->validateAuthKey(''))->false();
455
        expect("correct auth_key can be tested", $user->validateAuthKey($user->auth_key))->true();
456
457
        $user = $this->tester->grabFixture('users', 'blocked');
458
        $accessTokens['blocked'] = $user->access_token;
459
        expect("user getProfile() must return query", $user->getProfile())->isInstanceOf(yii\db\ActiveQuery::className());
460
        expect("we can get blocked user profile", $user->profile)->notEmpty();
461
        expect("blocked user can't be validated by auth_key", $user->validateAuthKey($user->auth_key))->false();
462
463
        $user = $this->tester->grabFixture('users', 'unconfirmed');
464
        $accessTokens['unconfirmed'] = $user->access_token;
465
        expect("we can get unconfirmed user profile", $user->getProfile()->one())->notEmpty();
466
        expect("unconfirmed user can't be validated by auth_key", $user->validateAuthKey($user->auth_key))->false();
467
468
        $user = $this->tester->grabFixture('users', 'emptyauth');
469
        $accessTokens['emptyauth'] = $user->access_token;
470
        expect("we can get active user profile", $user->profile)->notEmpty();
471
        expect("user with empty auth_key can't be validated by auth_key", $user->validateAuthKey(''))->false();
472
473
        expect("founded identity must be equals", User::findIdentity($user->id)->toArray())->equals($user->toArray());
474
        expect("identity cannot be found", User::findIdentity(99999))->isEmpty();
475
476
        expect('only active user can be founded by access token', User::findIdentityByAccessToken($accessTokens['active']))->notNull();
477
        expect('only active user can be founded by access token', User::findIdentityByAccessToken($accessTokens['emptyauth']))->notNull();
478
        expect('blocked user cannot be founded by access token', User::findIdentityByAccessToken($accessTokens['blocked']))->null();
479
        expect('unconfirmed user cannot be founded by access token', User::findIdentityByAccessToken($accessTokens['unconfirmed']))->null();
480
        expect('user with empty access token cannot be founded by access token', User::findIdentityByAccessToken(''))->null();
481
482
        expect("we cannot find user by empty token", User::findByToken(''))->null();
483
        expect("we cannot find user by null-value token", User::findByToken(null))->null();
484
        expect("we cannot find user by wrong token", User::findByToken('1'))->null();
485
486
        // check false before save
487
        $user = new User([
488
            'email' => '[email protected]',
489
            'password' => 'pass',
490
            'name' => 'Name',
491
        ]);
492
        $user->on(yii\db\BaseActiveRecord::EVENT_BEFORE_INSERT, function ($event) {
493
            /** @var yii\base\ModelEvent $event */
494
            $event->isValid = false;
495
            $event->sender->addError('event', 'Error event');
496
        });
497
        expect("user cannot be saved", $user->save())->false();
498
        expect("we can see error", $user->getErrors())->hasKey('event');
499
        expect("password hash must be empty", $user->pass_hash)->isEmpty();
500
    }
501
502
    protected function _before()
503
    {
504
        parent::_before();
505
        $this->tester->haveFixtures([
506
            'users' => UserFixture::className(),
507
            'profiles' => ProfileFixture::className(),
508
        ]);
509
    }
510
511
    protected function tearDown()
512
    {
513
        parent::tearDown();
514
    }
515
516
    protected function setUp()
517
    {
518
        parent::setUp();
519
        $this->module = Yii::$app->getModule('activeuser');
520
    }
521
522
    public function specify($specification, \Closure $callable = null, $params = [])
523
    {
524
        Yii::$app->mailer->reset();
525
        $this->parentSpecify($specification, $callable, $params);
526
    }
527
}
528