diff --git a/common/components/EmailsRenderer/Component.php b/common/components/EmailsRenderer/Component.php index f7e6dbe..8adc39f 100644 --- a/common/components/EmailsRenderer/Component.php +++ b/common/components/EmailsRenderer/Component.php @@ -4,14 +4,12 @@ declare(strict_types=1); namespace common\components\EmailsRenderer; use common\components\EmailsRenderer\Request\TemplateRequest; +use common\emails\RendererInterface; use Yii; use yii\base\InvalidConfigException; use yii\helpers\ArrayHelper; use yii\helpers\FileHelper; -/** - * @property string $baseDomain - */ class Component extends \yii\base\Component implements RendererInterface { /** @@ -20,8 +18,12 @@ class Component extends \yii\base\Component implements RendererInterface { public $serviceUrl; /** - * @var string базовый путь после хоста. Должен начинаться слешем и заканчиваться без него. - * Например "/email-images" + * @var string application base domain. Can be omitted for web applications (will be extracted from request) + */ + public $baseDomain; + + /** + * @var string base path after the host. For example "/emails-images" */ public $basePath = ''; @@ -30,11 +32,6 @@ class Component extends \yii\base\Component implements RendererInterface { */ private $api; - /** - * @var string - */ - private $_baseDomain; - public function init(): void { parent::init(); @@ -42,22 +39,14 @@ class Component extends \yii\base\Component implements RendererInterface { throw new InvalidConfigException('serviceUrl is required'); } - if ($this->_baseDomain === null) { - $this->_baseDomain = Yii::$app->urlManager->getHostInfo(); - if ($this->_baseDomain === null) { + if ($this->baseDomain === null) { + $this->baseDomain = Yii::$app->urlManager->getHostInfo(); + if ($this->baseDomain === null) { throw new InvalidConfigException('Cannot automatically obtain base domain'); } } } - public function setBaseDomain(string $baseDomain): void { - $this->_baseDomain = $baseDomain; - } - - public function getBaseDomain(): string { - return $this->_baseDomain; - } - /** * @param string $templateName * @param string $locale @@ -83,7 +72,7 @@ class Component extends \yii\base\Component implements RendererInterface { } private function buildBasePath(): string { - return FileHelper::normalizePath($this->_baseDomain . '/' . $this->basePath, '/'); + return FileHelper::normalizePath($this->baseDomain . '/' . $this->basePath, '/'); } } diff --git a/common/config/config-test.php b/common/config/config-test.php index 091aba4..2cffd5e 100644 --- a/common/config/config-test.php +++ b/common/config/config-test.php @@ -19,5 +19,8 @@ return [ 'mailer' => [ 'useFileTransport' => true, ], + 'emailsRenderer' => [ + 'class' => common\tests\_support\EmailsRenderer::class, + ], ], ]; diff --git a/common/components/EmailsRenderer/RendererInterface.php b/common/emails/RendererInterface.php similarity index 78% rename from common/components/EmailsRenderer/RendererInterface.php rename to common/emails/RendererInterface.php index ad4804e..1d8f101 100644 --- a/common/components/EmailsRenderer/RendererInterface.php +++ b/common/emails/RendererInterface.php @@ -1,7 +1,7 @@ user's name] - */ - public function __construct($to) { - $this->mailer = Yii::$app->mailer; - $this->to = $to; - } - - /** - * @return array|string - */ - public function getTo() { - return $this->to; + public function __construct(MailerInterface $mailer) { + $this->mailer = $mailer; } abstract public function getSubject(): string; @@ -44,7 +26,7 @@ abstract class Template { * @throws InvalidConfigException */ public function getFrom() { - $fromEmail = Yii::$app->params['fromEmail']; + $fromEmail = Yii::$app->params['fromEmail'] ?? ''; if (!$fromEmail) { throw new InvalidConfigException('Please specify fromEmail app in app params'); } @@ -56,13 +38,14 @@ abstract class Template { return []; } - public function getMailer(): MailerInterface { - return $this->mailer; - } - - public function send(): void { - if (!$this->createMessage()->send()) { - throw new CannotSendEmailException('Unable send email.'); + /** + * @param string|array $to see \yii\mail\MessageInterface::setTo to know the format. + * + * @throws \common\emails\exceptions\CannotSendEmailException + */ + public function send($to): void { + if (!$this->createMessage($to)->send()) { + throw new exceptions\CannotSendEmailException(); } } @@ -71,10 +54,14 @@ abstract class Template { */ abstract protected function getView(); - protected function createMessage(): MessageInterface { + final protected function getMailer(): MailerInterface { + return $this->mailer; + } + + protected function createMessage($for): MessageInterface { return $this->getMailer() ->compose($this->getView(), $this->getParams()) - ->setTo($this->getTo()) + ->setTo($for) ->setFrom($this->getFrom()) ->setSubject($this->getSubject()); } diff --git a/common/emails/TemplateWithRenderer.php b/common/emails/TemplateWithRenderer.php index 851c3d4..8e912d6 100644 --- a/common/emails/TemplateWithRenderer.php +++ b/common/emails/TemplateWithRenderer.php @@ -3,9 +3,8 @@ declare(strict_types=1); namespace common\emails; -use common\components\EmailsRenderer\RendererInterface; -use ErrorException; use Exception; +use yii\mail\MailerInterface; use yii\mail\MessageInterface; abstract class TemplateWithRenderer extends Template { @@ -18,59 +17,61 @@ abstract class TemplateWithRenderer extends Template { /** * @var string */ - private $locale; + private $locale = 'en'; - /** - * @inheritdoc - */ - public function __construct($to, string $locale, RendererInterface $renderer) { - parent::__construct($to); - $this->locale = $locale; + public function __construct(MailerInterface $mailer, RendererInterface $renderer) { + parent::__construct($mailer); $this->renderer = $renderer; } + public function setLocale(string $locale): void { + $this->locale = $locale; + } + public function getLocale(): string { return $this->locale; } - public function getRenderer(): RendererInterface { - return $this->renderer; - } - /** - * Метод должен возвращать имя шаблона, который должен быть использован. - * Имена можно взять в репозитории elyby/email-renderer + * This method should return the template's name, which will be rendered. + * List of available templates names can be found at https://github.com/elyby/emails-renderer * * @return string */ abstract public function getTemplateName(): string; + final protected function getRenderer(): RendererInterface { + return $this->renderer; + } + final protected function getView() { return $this->getTemplateName(); } /** + * @param string|array $for + * * @return MessageInterface - * @throws ErrorException + * @throws \common\emails\exceptions\CannotRenderEmailException */ - protected function createMessage(): MessageInterface { + protected function createMessage($for): MessageInterface { return $this->getMailer() ->compose() ->setHtmlBody($this->render()) - ->setTo($this->getTo()) + ->setTo($for) ->setFrom($this->getFrom()) ->setSubject($this->getSubject()); } /** * @return string - * @throws ErrorException + * @throws \common\emails\exceptions\CannotRenderEmailException */ private function render(): string { try { return $this->getRenderer()->render($this->getTemplateName(), $this->getLocale(), $this->getParams()); } catch (Exception $e) { - throw new ErrorException('Unable to render the template', 0, 1, __FILE__, __LINE__, $e); + throw new exceptions\CannotRenderEmailException($e); } } diff --git a/common/emails/exceptions/CannotRenderEmailException.php b/common/emails/exceptions/CannotRenderEmailException.php new file mode 100644 index 0000000..456e313 --- /dev/null +++ b/common/emails/exceptions/CannotRenderEmailException.php @@ -0,0 +1,15 @@ +key = $key; } @@ -19,14 +22,15 @@ class ChangeEmailConfirmCurrentEmail extends Template { } public function getParams(): array { + if ($this->key === null) { + throw new InvalidCallException('You need to set key param first'); + } + return [ 'key' => $this->key, ]; } - /** - * @return string|array - */ protected function getView() { return [ 'html' => '@common/emails/views/current-email-confirmation-html', diff --git a/common/emails/templates/ChangeEmailConfirmNewEmail.php b/common/emails/templates/ConfirmNewEmail.php similarity index 62% rename from common/emails/templates/ChangeEmailConfirmNewEmail.php rename to common/emails/templates/ConfirmNewEmail.php index ac32c10..de19655 100644 --- a/common/emails/templates/ChangeEmailConfirmNewEmail.php +++ b/common/emails/templates/ConfirmNewEmail.php @@ -4,16 +4,25 @@ declare(strict_types=1); namespace common\emails\templates; use common\emails\Template; +use yii\base\InvalidCallException; -class ChangeEmailConfirmNewEmail extends Template { +class ConfirmNewEmail extends Template { + /** + * @var string|null + */ private $username; + /** + * @var string|null + */ private $key; - public function __construct($to, string $username, string $key) { - parent::__construct($to); + public function setUsername(string $username): void { $this->username = $username; + } + + public function setKey(string $key): void { $this->key = $key; } @@ -22,15 +31,16 @@ class ChangeEmailConfirmNewEmail extends Template { } public function getParams(): array { + if ($this->username === null || $this->key === null) { + throw new InvalidCallException('You need to set username and key params first'); + } + return [ - 'key' => $this->key, 'username' => $this->username, + 'key' => $this->key, ]; } - /** - * @return string|array - */ protected function getView() { return [ 'html' => '@common/emails/views/new-email-confirmation-html', diff --git a/common/emails/templates/ForgotPasswordEmail.php b/common/emails/templates/ForgotPasswordEmail.php index 51c9e4e..ce50b4c 100644 --- a/common/emails/templates/ForgotPasswordEmail.php +++ b/common/emails/templates/ForgotPasswordEmail.php @@ -3,20 +3,15 @@ declare(strict_types=1); namespace common\emails\templates; -use common\components\EmailsRenderer\RendererInterface; use common\emails\TemplateWithRenderer; +use yii\base\InvalidCallException; class ForgotPasswordEmail extends TemplateWithRenderer { - private $params; - /** - * @inheritdoc + * @var ForgotPasswordParams|null */ - public function __construct($to, string $locale, ForgotPasswordParams $params, RendererInterface $renderer) { - parent::__construct($to, $locale, $renderer); - $this->params = $params; - } + private $params; public function getSubject(): string { return 'Ely.by Account forgot password'; @@ -26,7 +21,15 @@ class ForgotPasswordEmail extends TemplateWithRenderer { return 'forgotPassword'; } + public function setParams(ForgotPasswordParams $params): void { + $this->params = $params; + } + public function getParams(): array { + if ($this->params === null) { + throw new InvalidCallException('You need to set params first'); + } + return [ 'username' => $this->params->getUsername(), 'code' => $this->params->getCode(), diff --git a/common/emails/templates/RegistrationEmail.php b/common/emails/templates/RegistrationEmail.php index 8cf0893..ca065b8 100644 --- a/common/emails/templates/RegistrationEmail.php +++ b/common/emails/templates/RegistrationEmail.php @@ -3,20 +3,15 @@ declare(strict_types=1); namespace common\emails\templates; -use common\components\EmailsRenderer\RendererInterface; use common\emails\TemplateWithRenderer; +use yii\base\InvalidCallException; class RegistrationEmail extends TemplateWithRenderer { - private $params; - /** - * @inheritdoc + * @var RegistrationEmailParams|null */ - public function __construct($to, string $locale, RegistrationEmailParams $params, RendererInterface $renderer) { - parent::__construct($to, $locale, $renderer); - $this->params = $params; - } + private $params; public function getSubject(): string { return 'Ely.by Account registration'; @@ -26,7 +21,15 @@ class RegistrationEmail extends TemplateWithRenderer { return 'register'; } + public function setParams(RegistrationEmailParams $params): void { + $this->params = $params; + } + public function getParams(): array { + if ($this->params === null) { + throw new InvalidCallException('You need to set params first'); + } + return [ 'username' => $this->params->getUsername(), 'code' => $this->params->getCode(), diff --git a/common/tasks/SendCurrentEmailConfirmation.php b/common/tasks/SendCurrentEmailConfirmation.php index fe0285e..7396c8e 100644 --- a/common/tasks/SendCurrentEmailConfirmation.php +++ b/common/tasks/SendCurrentEmailConfirmation.php @@ -1,9 +1,10 @@ statsd->inc('queue.sendCurrentEmailConfirmation.attempt'); - $to = EmailHelper::buildTo($this->username, $this->email); - $template = new ChangeEmailConfirmCurrentEmail($to, $this->code); - $template->send(); + $template = new ChangeEmail(Yii::$app->mailer); + $template->setKey($this->code); + $template->send(EmailHelper::buildTo($this->username, $this->email)); } } diff --git a/common/tasks/SendNewEmailConfirmation.php b/common/tasks/SendNewEmailConfirmation.php index da034ff..0f7fcd4 100644 --- a/common/tasks/SendNewEmailConfirmation.php +++ b/common/tasks/SendNewEmailConfirmation.php @@ -1,9 +1,10 @@ statsd->inc('queue.sendNewEmailConfirmation.attempt'); - $to = EmailHelper::buildTo($this->username, $this->email); - $template = new ChangeEmailConfirmNewEmail($to, $this->username, $this->code); - $template->send(); + $template = new ConfirmNewEmail(Yii::$app->mailer); + $template->setKey($this->code); + $template->setUsername($this->username); + $template->send(EmailHelper::buildTo($this->username, $this->email)); } } diff --git a/common/tasks/SendPasswordRecoveryEmail.php b/common/tasks/SendPasswordRecoveryEmail.php index 41689ea..d9a90c4 100644 --- a/common/tasks/SendPasswordRecoveryEmail.php +++ b/common/tasks/SendPasswordRecoveryEmail.php @@ -1,5 +1,6 @@ statsd->inc('queue.sendPasswordRecovery.attempt'); - $params = new ForgotPasswordParams($this->username, $this->code, $this->link); - $to = EmailHelper::buildTo($this->username, $this->email); - $template = new ForgotPasswordEmail($to, $this->locale, $params, Yii::$app->emailsRenderer); - $template->send(); + $template = new ForgotPasswordEmail(Yii::$app->mailer, Yii::$app->emailsRenderer); + $template->setLocale($this->locale); + $template->setParams(new ForgotPasswordParams($this->username, $this->code, $this->link)); + $template->send(EmailHelper::buildTo($this->username, $this->email)); } } diff --git a/common/tasks/SendRegistrationEmail.php b/common/tasks/SendRegistrationEmail.php index 2a5e4fd..2380c80 100644 --- a/common/tasks/SendRegistrationEmail.php +++ b/common/tasks/SendRegistrationEmail.php @@ -1,5 +1,6 @@ statsd->inc('queue.sendRegistrationEmail.attempt'); - $params = new RegistrationEmailParams($this->username, $this->code, $this->link); - $to = EmailHelper::buildTo($this->username, $this->email); - $template = new RegistrationEmail($to, $this->locale, $params, Yii::$app->emailsRenderer); - $template->send(); + $template = new RegistrationEmail(Yii::$app->mailer, Yii::$app->emailsRenderer); + $template->setLocale($this->locale); + $template->setParams(new RegistrationEmailParams($this->username, $this->code, $this->link)); + $template->send(EmailHelper::buildTo($this->username, $this->email)); } } diff --git a/common/tests/_support/EmailsRenderer.php b/common/tests/_support/EmailsRenderer.php new file mode 100644 index 0000000..cf9670a --- /dev/null +++ b/common/tests/_support/EmailsRenderer.php @@ -0,0 +1,14 @@ +makePartial(); - $this->assertSame('find-me', $template->getTo()); - $this->assertInstanceOf(MailerInterface::class, $template->getMailer()); + /** + * @var Template|\PHPUnit\Framework\MockObject\MockObject $template + */ + private $template; + + /** + * @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $mailer; + + /** + * @var string + */ + private $initialFromEmail; + + public function testGetters() { + $this->assertSame(['find-me' => 'Ely.by Accounts'], $this->template->getFrom()); + $this->assertSame([], $this->template->getParams()); } - public function testGetFrom() { + public function testSend() { + $this->runTestForSend(true); + } + + public function testNotSend() { + $this->expectException(CannotSendEmailException::class); + $this->runTestForSend(false); + } + + protected function _before() { + parent::_before(); + $this->mailer = $this->createMock(MailerInterface::class); + $this->template = $this->getMockForAbstractClass(Template::class, [$this->mailer]); + $this->initialFromEmail = Yii::$app->params['fromEmail']; Yii::$app->params['fromEmail'] = 'find-me'; - /** @var Template|\Mockery\MockInterface $template */ - $template = mock(Template::class)->makePartial(); - $this->assertSame(['find-me' => 'Ely.by Accounts'], $template->getFrom()); } - public function testGetParams() { - /** @var Template|\Mockery\MockInterface $template */ - $template = mock(Template::class)->makePartial(); - $this->assertSame([], $template->getParams()); + protected function _after() { + parent::_after(); + Yii::$app->params['fromEmail'] = $this->initialFromEmail; } - public function testCreateMessage() { - Yii::$app->params['fromEmail'] = 'from@ely.by'; - /** @var Template|\Mockery\MockInterface $template */ - $template = mock(Template::class, [['to@ely.by' => 'To']])->makePartial(); - $template->shouldReceive('getSubject')->andReturn('mock-subject'); - /** @var MessageInterface $message */ - $message = $this->callProtected($template, 'createMessage'); - $this->assertInstanceOf(MessageInterface::class, $message); - $this->assertSame(['to@ely.by' => 'To'], $message->getTo()); - $this->assertSame(['from@ely.by' => 'Ely.by Accounts'], $message->getFrom()); - $this->assertSame('mock-subject', $message->getSubject()); + private function runTestForSend(bool $sendResult) { + $this->template->expects($this->once())->method('getSubject')->willReturn('mock-subject'); + $this->template->expects($this->once())->method('getView')->willReturn('mock-view'); + + /** @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject $message */ + $message = $this->createMock(MessageInterface::class); + $message->expects($this->once())->method('setTo')->with(['to@ely.by' => 'To'])->willReturnSelf(); + $message->expects($this->once())->method('setFrom')->with(['find-me' => 'Ely.by Accounts'])->willReturnSelf(); + $message->expects($this->once())->method('setSubject')->with('mock-subject')->willReturnSelf(); + $message->expects($this->once())->method('send')->willReturn($sendResult); + + $this->mailer->expects($this->once())->method('compose')->with('mock-view', [])->willReturn($message); + + $this->template->send(['to@ely.by' => 'To']); } } diff --git a/common/tests/unit/emails/TemplateWithRendererTest.php b/common/tests/unit/emails/TemplateWithRendererTest.php index 3144871..acb923f 100644 --- a/common/tests/unit/emails/TemplateWithRendererTest.php +++ b/common/tests/unit/emails/TemplateWithRendererTest.php @@ -1,49 +1,103 @@ makePartial(); - $this->assertSame('mock-to', $template->getTo()); - $this->assertSame('mock-locale', $template->getLocale()); - $this->assertInstanceOf(MailerInterface::class, $template->getMailer()); - $this->assertInstanceOf(Component::class, $template->getRenderer()); + /** + * @var TemplateWithRenderer|\PHPUnit\Framework\MockObject\MockObject $template + */ + private $template; + + /** + * @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $mailer; + + /** + * @var RendererInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $renderer; + + /** + * @var string + */ + private $initialFromEmail; + + public function testGetLocale() { + $this->assertSame('en', $this->template->getLocale()); + $this->template->setLocale('find me'); + $this->assertSame('find me', $this->template->getLocale()); } - public function testCreateMessage() { - /** @var TemplateBuilder|\Mockery\MockInterface $templateBuilder */ - $templateBuilder = mock(TemplateBuilder::class)->makePartial(); - $templateBuilder->shouldReceive('render')->andReturn('mock-html'); + public function testSend() { + $this->runTestForSend(); + } - /** @var Component|\Mockery\MockInterface $renderer */ - $renderer = mock(Component::class)->makePartial(); - $renderer->shouldReceive('getTemplate')->with('mock-template')->andReturn($templateBuilder); + public function testSendWithRenderError() { + $renderException = new Exception('find me'); + try { + $this->runTestForSend($renderException); + } catch (CannotRenderEmailException $e) { + // Catch exception manually to assert the previous exception + $this->assertSame('Unable to render a template', $e->getMessage()); + $this->assertSame($renderException, $e->getPrevious()); - /** @var TemplateWithRenderer|\Mockery\MockInterface $template */ - $template = mock(TemplateWithRenderer::class, [['to@ely.by' => 'To'], 'mock-locale']); - $template->makePartial(); - $template->shouldReceive('getEmailRenderer')->andReturn($renderer); - $template->shouldReceive('getFrom')->andReturn(['from@ely.by' => 'From']); - $template->shouldReceive('getSubject')->andReturn('mock-subject'); - $template->shouldReceive('getTemplateName')->andReturn('mock-template'); - /** @var \yii\swiftmailer\Message $message */ - $message = $this->callProtected($template, 'createMessage'); - $this->assertInstanceOf(MessageInterface::class, $message); - $this->assertSame(['to@ely.by' => 'To'], $message->getTo()); - $this->assertSame(['from@ely.by' => 'From'], $message->getFrom()); - $this->assertSame('mock-subject', $message->getSubject()); - $this->assertSame('mock-html', $message->getSwiftMessage()->getBody()); + return; + } + + $this->assertFalse(true, 'no exception was thrown'); + } + + protected function _before() { + parent::_before(); + $this->mailer = $this->createMock(MailerInterface::class); + $this->renderer = $this->createMock(RendererInterface::class); + $this->template = $this->getMockForAbstractClass(TemplateWithRenderer::class, [$this->mailer, $this->renderer]); + $this->initialFromEmail = Yii::$app->params['fromEmail']; + Yii::$app->params['fromEmail'] = 'find-me'; + } + + protected function _after() { + parent::_after(); + Yii::$app->params['fromEmail'] = $this->initialFromEmail; + } + + private function runTestForSend($renderException = null) { + $renderMethodExpectation = $this->renderer->expects($this->once())->method('render')->with('mock-template', 'mock-locale', []); + if ($renderException === null) { + $renderMethodExpectation->willReturn('mock-template-contents'); + $times = [$this, 'once']; + } else { + $renderMethodExpectation->willThrowException($renderException); + $times = [$this, 'any']; + } + + $this->template->expects($times())->method('getSubject')->willReturn('mock-subject'); + $this->template->expects($times())->method('getTemplateName')->willReturn('mock-template'); + + /** @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject $message */ + $message = $this->createMock(MessageInterface::class); + $message->expects($times())->method('setTo')->with(['to@ely.by' => 'To'])->willReturnSelf(); + $message->expects($times())->method('setHtmlBody')->with('mock-template-contents')->willReturnSelf(); + $message->expects($times())->method('setFrom')->with(['find-me' => 'Ely.by Accounts'])->willReturnSelf(); + $message->expects($times())->method('setSubject')->with('mock-subject')->willReturnSelf(); + $message->expects($times())->method('send')->willReturn(true); + + $this->mailer->expects($times())->method('compose')->willReturn($message); + + $this->template->setLocale('mock-locale'); + $this->template->send(['to@ely.by' => 'To']); } } diff --git a/common/tests/unit/emails/templates/ChangeEmailTest.php b/common/tests/unit/emails/templates/ChangeEmailTest.php new file mode 100644 index 0000000..e9a1724 --- /dev/null +++ b/common/tests/unit/emails/templates/ChangeEmailTest.php @@ -0,0 +1,36 @@ +template->setKey('mock-key'); + $params = $this->template->getParams(); + $this->assertSame('mock-key', $params['key']); + } + + public function testInvalidCallOfParams() { + $this->expectException(InvalidCallException::class); + $this->template->getParams(); + } + + protected function _before() { + parent::_before(); + /** @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject $mailer */ + $mailer = $this->createMock(MailerInterface::class); + $this->template = new ChangeEmail($mailer); + } + +} diff --git a/common/tests/unit/emails/templates/ConfirmNewEmailTest.php b/common/tests/unit/emails/templates/ConfirmNewEmailTest.php new file mode 100644 index 0000000..266b72d --- /dev/null +++ b/common/tests/unit/emails/templates/ConfirmNewEmailTest.php @@ -0,0 +1,49 @@ +template->setUsername('mock-username'); + $this->template->setKey('mock-key'); + $params = $this->template->getParams(); + $this->assertSame('mock-username', $params['username']); + $this->assertSame('mock-key', $params['key']); + } + + /** + * @dataProvider getInvalidCallsCases + */ + public function testInvalidCallOfParams(?string $username, ?string $key) { + $this->expectException(InvalidCallException::class); + $username !== null && $this->template->setUsername($username); + $key !== null && $this->template->setKey($key); + $this->template->getParams(); + } + + public function getInvalidCallsCases() { + yield [null, null]; + yield ['value', null]; + yield [null, 'value']; + } + + protected function _before() { + parent::_before(); + /** @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject $mailer */ + $mailer = $this->createMock(MailerInterface::class); + $this->template = new ConfirmNewEmail($mailer); + } + +} diff --git a/common/tests/unit/emails/templates/ForgotPasswordEmailTest.php b/common/tests/unit/emails/templates/ForgotPasswordEmailTest.php new file mode 100644 index 0000000..f8c61d5 --- /dev/null +++ b/common/tests/unit/emails/templates/ForgotPasswordEmailTest.php @@ -0,0 +1,42 @@ +template->setParams(new ForgotPasswordParams('mock-username', 'mock-code', 'mock-link')); + $params = $this->template->getParams(); + $this->assertSame('mock-username', $params['username']); + $this->assertSame('mock-code', $params['code']); + $this->assertSame('mock-link', $params['link']); + } + + public function testInvalidCallOfParams() { + $this->expectException(InvalidCallException::class); + $this->template->getParams(); + } + + protected function _before() { + parent::_before(); + /** @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject $mailer */ + $mailer = $this->createMock(MailerInterface::class); + /** @var RendererInterface|\PHPUnit\Framework\MockObject\MockObject $renderer */ + $renderer = $this->createMock(RendererInterface::class); + $this->template = new ForgotPasswordEmail($mailer, $renderer); + } + +} diff --git a/common/tests/unit/emails/templates/RegistrationEmailTest.php b/common/tests/unit/emails/templates/RegistrationEmailTest.php new file mode 100644 index 0000000..f2f36c9 --- /dev/null +++ b/common/tests/unit/emails/templates/RegistrationEmailTest.php @@ -0,0 +1,42 @@ +template->setParams(new RegistrationEmailParams('mock-username', 'mock-code', 'mock-link')); + $params = $this->template->getParams(); + $this->assertSame('mock-username', $params['username']); + $this->assertSame('mock-code', $params['code']); + $this->assertSame('mock-link', $params['link']); + } + + public function testInvalidCallOfParams() { + $this->expectException(InvalidCallException::class); + $this->template->getParams(); + } + + protected function _before() { + parent::_before(); + /** @var MailerInterface|\PHPUnit\Framework\MockObject\MockObject $mailer */ + $mailer = $this->createMock(MailerInterface::class); + /** @var RendererInterface|\PHPUnit\Framework\MockObject\MockObject $renderer */ + $renderer = $this->createMock(RendererInterface::class); + $this->template = new RegistrationEmail($mailer, $renderer); + } + +} diff --git a/common/tests/unit/tasks/SendPasswordRecoveryEmailTest.php b/common/tests/unit/tasks/SendPasswordRecoveryEmailTest.php index 0b86507..0112df0 100644 --- a/common/tests/unit/tasks/SendPasswordRecoveryEmailTest.php +++ b/common/tests/unit/tasks/SendPasswordRecoveryEmailTest.php @@ -1,14 +1,23 @@ username = 'mock-username'; @@ -21,7 +30,6 @@ class SendPasswordRecoveryEmailTest extends TestCase { $confirmation->shouldReceive('getAccount')->andReturn($account); $result = SendPasswordRecoveryEmail::createFromConfirmation($confirmation); - $this->assertInstanceOf(SendPasswordRecoveryEmail::class, $result); $this->assertSame('mock-username', $result->username); $this->assertSame('mock@ely.by', $result->email); $this->assertSame('ABCDEFG', $result->code); @@ -37,6 +45,12 @@ class SendPasswordRecoveryEmailTest extends TestCase { $task->link = 'https://account.ely.by/recover-password/ABCDEFG'; $task->locale = 'ru'; + $this->renderer->expects($this->once())->method('render')->with('forgotPassword', 'ru', [ + 'username' => 'mock-username', + 'code' => 'GFEDCBA', + 'link' => 'https://account.ely.by/recover-password/ABCDEFG', + ])->willReturn('mock-template'); + $task->execute(mock(Queue::class)); $this->tester->canSeeEmailIsSent(1); @@ -44,10 +58,14 @@ class SendPasswordRecoveryEmailTest extends TestCase { $email = $this->tester->grabSentEmails()[0]; $this->assertSame(['mock@ely.by' => 'mock-username'], $email->getTo()); $this->assertSame('Ely.by Account forgot password', $email->getSubject()); - $body = $email->getSwiftMessage()->getBody(); - $this->assertContains('Привет, mock-username', $body); - $this->assertContains('GFEDCBA', $body); - $this->assertContains('https://account.ely.by/recover-password/ABCDEFG', $body); + $this->assertSame('mock-template', $email->getSwiftMessage()->getBody()); + } + + protected function _before() { + parent::_before(); + + $this->renderer = $this->createMock(RendererInterface::class); + Yii::$app->set('emailsRenderer', $this->renderer); } } diff --git a/common/tests/unit/tasks/SendRegistrationEmailTest.php b/common/tests/unit/tasks/SendRegistrationEmailTest.php index 229001a..1cc69d4 100644 --- a/common/tests/unit/tasks/SendRegistrationEmailTest.php +++ b/common/tests/unit/tasks/SendRegistrationEmailTest.php @@ -1,14 +1,23 @@ username = 'mock-username'; @@ -21,7 +30,6 @@ class SendRegistrationEmailTest extends TestCase { $confirmation->shouldReceive('getAccount')->andReturn($account); $result = SendRegistrationEmail::createFromConfirmation($confirmation); - $this->assertInstanceOf(SendRegistrationEmail::class, $result); $this->assertSame('mock-username', $result->username); $this->assertSame('mock@ely.by', $result->email); $this->assertSame('ABCDEFG', $result->code); @@ -37,17 +45,27 @@ class SendRegistrationEmailTest extends TestCase { $task->link = 'https://account.ely.by/activation/ABCDEFG'; $task->locale = 'ru'; - $task->execute(mock(Queue::class)); + $this->renderer->expects($this->once())->method('render')->with('register', 'ru', [ + 'username' => 'mock-username', + 'code' => 'GFEDCBA', + 'link' => 'https://account.ely.by/activation/ABCDEFG', + ])->willReturn('mock-template'); + + $task->execute($this->createMock(Queue::class)); $this->tester->canSeeEmailIsSent(1); /** @var \yii\swiftmailer\Message $email */ $email = $this->tester->grabSentEmails()[0]; $this->assertSame(['mock@ely.by' => 'mock-username'], $email->getTo()); $this->assertSame('Ely.by Account registration', $email->getSubject()); - $body = $email->getSwiftMessage()->getBody(); - $this->assertContains('Привет, mock-username', $body); - $this->assertContains('GFEDCBA', $body); - $this->assertContains('https://account.ely.by/activation/ABCDEFG', $body); + $this->assertSame('mock-template', $email->getSwiftMessage()->getBody()); + } + + protected function _before() { + parent::_before(); + + $this->renderer = $this->createMock(RendererInterface::class); + Yii::$app->set('emailsRenderer', $this->renderer); } }