diff --git a/app/code/Magento/Contact/Controller/Index.php b/app/code/Magento/Contact/Controller/Index.php index a646b69dba17f..3b170f7c4841c 100644 --- a/app/code/Magento/Contact/Controller/Index.php +++ b/app/code/Magento/Contact/Controller/Index.php @@ -5,74 +5,51 @@ */ namespace Magento\Contact\Controller; -use Magento\Framework\Exception\NotFoundException; +use Magento\Contact\Model\ConfigInterface; +use Magento\Framework\App\Action\Context; use Magento\Framework\App\RequestInterface; -use Magento\Store\Model\ScopeInterface; +use Magento\Framework\Exception\NotFoundException; /** - * Contact index controller + * Contact module base controller */ abstract class Index extends \Magento\Framework\App\Action\Action { /** * Recipient email config path */ - const XML_PATH_EMAIL_RECIPIENT = 'contact/email/recipient_email'; + const XML_PATH_EMAIL_RECIPIENT = ConfigInterface::XML_PATH_EMAIL_RECIPIENT; /** * Sender email config path */ - const XML_PATH_EMAIL_SENDER = 'contact/email/sender_email_identity'; + const XML_PATH_EMAIL_SENDER = ConfigInterface::XML_PATH_EMAIL_SENDER; /** * Email template config path */ - const XML_PATH_EMAIL_TEMPLATE = 'contact/email/email_template'; + const XML_PATH_EMAIL_TEMPLATE = ConfigInterface::XML_PATH_EMAIL_TEMPLATE; /** * Enabled config path */ - const XML_PATH_ENABLED = 'contact/contact/enabled'; - - /** - * @var \Magento\Framework\Mail\Template\TransportBuilder - */ - protected $_transportBuilder; - - /** - * @var \Magento\Framework\Translate\Inline\StateInterface - */ - protected $inlineTranslation; - - /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface - */ - protected $scopeConfig; + const XML_PATH_ENABLED = ConfigInterface::XML_PATH_ENABLED; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var ConfigInterface */ - protected $storeManager; + private $contactsConfig; /** - * @param \Magento\Framework\App\Action\Context $context - * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder - * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param Context $context * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param \Magento\Store\Model\StoreManagerInterface $storeManager */ public function __construct( - \Magento\Framework\App\Action\Context $context, - \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder, - \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, - \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - \Magento\Store\Model\StoreManagerInterface $storeManager + Context $context, + ConfigInterface $contactsConfig ) { parent::__construct($context); - $this->_transportBuilder = $transportBuilder; - $this->inlineTranslation = $inlineTranslation; - $this->scopeConfig = $scopeConfig; - $this->storeManager = $storeManager; + $this->contactsConfig = $contactsConfig; } /** @@ -84,7 +61,7 @@ public function __construct( */ public function dispatch(RequestInterface $request) { - if (!$this->scopeConfig->isSetFlag(self::XML_PATH_ENABLED, ScopeInterface::SCOPE_STORE)) { + if (!$this->contactsConfig->isEnabled()) { throw new NotFoundException(__('Page not found.')); } return parent::dispatch($request); diff --git a/app/code/Magento/Contact/Controller/Index/Post.php b/app/code/Magento/Contact/Controller/Index/Post.php index 9ad831befd06f..8f94dfbd98213 100644 --- a/app/code/Magento/Contact/Controller/Index/Post.php +++ b/app/code/Magento/Contact/Controller/Index/Post.php @@ -6,8 +6,16 @@ */ namespace Magento\Contact\Controller\Index; -use Magento\Framework\App\Request\DataPersistorInterface; +use Magento\Contact\Model\ConfigInterface; +use Magento\Contact\Model\MailInterface; +use Magento\Framework\App\Action\Context; use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\Request\DataPersistorInterface; +use Magento\Framework\Controller\Result\Redirect; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\HTTP\PhpEnvironment\Request; +use Magento\Framework\Mail\Template\TransportBuilder; +use Magento\Framework\Translate\Inline\StateInterface; class Post extends \Magento\Contact\Controller\Index { @@ -16,75 +24,60 @@ class Post extends \Magento\Contact\Controller\Index */ private $dataPersistor; + /** + * @var Context + */ + private $context; + + /** + * @var MailInterface + */ + private $mail; + + /** + * @param Context $context + * @param MailInterface $mail + * @param ConfigInterface $contactsConfig + * @param DataPersistorInterface $dataPersistor + */ + public function __construct( + Context $context, + MailInterface $mail, + ConfigInterface $contactsConfig, + DataPersistorInterface $dataPersistor + ) { + parent::__construct($context, $contactsConfig); + $this->context = $context; + $this->mail = $mail; + $this->dataPersistor = $dataPersistor; + } + /** * Post user question * - * @return void - * @throws \Exception + * @return Redirect */ public function execute() { - $post = $this->getRequest()->getPostValue(); - if (!$post) { - $this->_redirect('*/*/'); - return; + if (! $this->isPostRequest()) { + return $this->resultRedirectFactory->create()->setPath('*/*/'); } - - $this->inlineTranslation->suspend(); try { - $postObject = new \Magento\Framework\DataObject(); - $postObject->setData($post); - - $error = false; - - if (!\Zend_Validate::is(trim($post['name']), 'NotEmpty')) { - $error = true; - } - if (!\Zend_Validate::is(trim($post['comment']), 'NotEmpty')) { - $error = true; - } - if (!\Zend_Validate::is(trim($post['email']), 'EmailAddress')) { - $error = true; - } - if (\Zend_Validate::is(trim($post['hideit']), 'NotEmpty')) { - $error = true; - } - if ($error) { - throw new \Exception(); - } - - $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; - $transport = $this->_transportBuilder - ->setTemplateIdentifier($this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, $storeScope)) - ->setTemplateOptions( - [ - 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE, - 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, - ] - ) - ->setTemplateVars(['data' => $postObject]) - ->setFrom($this->scopeConfig->getValue(self::XML_PATH_EMAIL_SENDER, $storeScope)) - ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope)) - ->setReplyTo($post['email']) - ->getTransport(); - - $transport->sendMessage(); - $this->inlineTranslation->resume(); + $this->sendEmail($this->validatedParams()); $this->messageManager->addSuccess( __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.') ); $this->getDataPersistor()->clear('contact_us'); - $this->_redirect('contact/index'); - return; + } catch (LocalizedException $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + $this->getDataPersistor()->set('contact_us', $this->getRequest()->getParams()); } catch (\Exception $e) { - $this->inlineTranslation->resume(); - $this->messageManager->addError( + $this->messageManager->addErrorMessage( __('We can\'t process your request right now. Sorry, that\'s all we know.') ); - $this->getDataPersistor()->set('contact_us', $post); - $this->_redirect('contact/index'); - return; + $this->getDataPersistor()->set('contact_us', $this->getRequest()->getParams()); } + return $this->resultRedirectFactory->create()->setPath('contact/index'); } /** @@ -101,4 +94,46 @@ private function getDataPersistor() return $this->dataPersistor; } + + /** + * @param array $post Post data from contact form + * @return void + */ + private function sendEmail($post) + { + $this->mail->send($post['email'], ['data' => new \Magento\Framework\DataObject($post)]); + } + + /** + * @return bool + */ + private function isPostRequest() + { + /** @var Request $request */ + $request = $this->getRequest(); + return !empty($request->getPostValue()); + } + + /** + * @return array + * @throws \Exception + */ + private function validatedParams() + { + $request = $this->getRequest(); + if (trim($request->getParam('name')) === '') { + throw new LocalizedException(__('Name is missing')); + } + if (trim($request->getParam('comment')) === '') { + throw new LocalizedException(__('Comment is missing')); + } + if (false === \strpos($request->getParam('email'), '@')) { + throw new LocalizedException(__('Invalid email address')); + } + if (trim($request->getParam('hideit')) !== '') { + throw new \Exception(); + } + + return $request->getParams(); + } } diff --git a/app/code/Magento/Contact/Helper/Data.php b/app/code/Magento/Contact/Helper/Data.php index f6ad3d9d5a871..ff738e7e27996 100644 --- a/app/code/Magento/Contact/Helper/Data.php +++ b/app/code/Magento/Contact/Helper/Data.php @@ -6,6 +6,7 @@ namespace Magento\Contact\Helper; +use Magento\Contact\Model\ConfigInterface; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Helper\View as CustomerViewHelper; use Magento\Framework\App\Request\DataPersistorInterface; @@ -16,7 +17,7 @@ */ class Data extends \Magento\Framework\App\Helper\AbstractHelper { - const XML_PATH_ENABLED = 'contact/contact/enabled'; + const XML_PATH_ENABLED = ConfigInterface::XML_PATH_ENABLED; /** * Customer session @@ -59,6 +60,7 @@ public function __construct( * Check if enabled * * @return string|null + * @deprecated use \Magento\Contact\Api\ConfigInterface::isEnabled() instead */ public function isEnabled() { diff --git a/app/code/Magento/Contact/Model/Config.php b/app/code/Magento/Contact/Model/Config.php new file mode 100644 index 0000000000000..24e47af6f4dba --- /dev/null +++ b/app/code/Magento/Contact/Model/Config.php @@ -0,0 +1,73 @@ +scopeConfig = $scopeConfig; + } + + /** + * @return bool + */ + public function isEnabled() + { + return $this->scopeConfig->isSetFlag( + self::XML_PATH_ENABLED, + ScopeInterface::SCOPE_STORE + ); + } + + /** + * @return string + */ + public function emailTemplate() + { + return $this->scopeConfig->getValue( + ConfigInterface::XML_PATH_EMAIL_TEMPLATE, + ScopeInterface::SCOPE_STORE + ); + } + + /** + * @return string + */ + public function emailSender() + { + return $this->scopeConfig->getValue( + ConfigInterface::XML_PATH_EMAIL_SENDER, + ScopeInterface::SCOPE_STORE + ); + } + + /** + * @return string + */ + public function emailRecipient() + { + return $this->scopeConfig->getValue( + ConfigInterface::XML_PATH_EMAIL_RECIPIENT, + ScopeInterface::SCOPE_STORE + ); + } +} diff --git a/app/code/Magento/Contact/Model/ConfigInterface.php b/app/code/Magento/Contact/Model/ConfigInterface.php new file mode 100644 index 0000000000000..ac702bc6d30d3 --- /dev/null +++ b/app/code/Magento/Contact/Model/ConfigInterface.php @@ -0,0 +1,61 @@ +contactsConfig = $contactsConfig; + $this->transportBuilder = $transportBuilder; + $this->inlineTranslation = $inlineTranslation; + } + + /** + * Send email from contact form + * + * @param string $replyTo + * @param array $variables + * @return void + */ + public function send($replyTo, array $variables) + { + $this->inlineTranslation->suspend(); + try { + $transport = $this->transportBuilder + ->setTemplateIdentifier($this->contactsConfig->emailTemplate()) + ->setTemplateOptions( + [ + 'area' => 'adminhtml', + 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, + ] + ) + ->setTemplateVars($variables) + ->setFrom($this->contactsConfig->emailSender()) + ->addTo($this->contactsConfig->emailRecipient()) + ->setReplyTo($replyTo) + ->getTransport(); + + $transport->sendMessage(); + } finally { + $this->inlineTranslation->resume(); + } + } +} diff --git a/app/code/Magento/Contact/Model/MailInterface.php b/app/code/Magento/Contact/Model/MailInterface.php new file mode 100644 index 0000000000000..75c5453602c0e --- /dev/null +++ b/app/code/Magento/Contact/Model/MailInterface.php @@ -0,0 +1,22 @@ +_scopeConfig = $this->getMockForAbstractClass( - \Magento\Framework\App\Config\ScopeConfigInterface::class, - ['isSetFlag'], - '', - false - ); - $context = $this->getMock( - \Magento\Framework\App\Action\Context::class, - ['getRequest', 'getResponse', 'getResultFactory', 'getUrl'], - [], - '', - false - ); + $this->configMock = $this->getMockBuilder(ConfigInterface::class)->getMockForAbstractClass(); - $this->_url = $this->getMockForAbstractClass(\Magento\Framework\UrlInterface::class, [], '', false); + $context = $this->getMockBuilder( + \Magento\Framework\App\Action\Context::class + )->setMethods( + ['getRequest', 'getResponse', 'getResultFactory', 'getUrl'] + )->disableOriginalConstructor( + )->getMock(); + + $this->url = $this->getMockBuilder(\Magento\Framework\UrlInterface::class)->getMockForAbstractClass(); $context->expects($this->any()) ->method('getUrl') - ->will($this->returnValue($this->_url)); + ->will($this->returnValue($this->url)); $context->expects($this->any()) ->method('getRequest') ->will($this->returnValue( - $this->getMockForAbstractClass(\Magento\Framework\App\RequestInterface::class, [], '', false) + $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMockForAbstractClass() )); $context->expects($this->any()) ->method('getResponse') ->will($this->returnValue( - $this->getMockForAbstractClass(\Magento\Framework\App\ResponseInterface::class, [], '', false) + $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class)->getMockForAbstractClass() )); - $this->resultFactory = $this->getMock( - ResultFactory::class, - [], - [], - '', - false - ); + $this->resultFactory = $this->getMockBuilder( + ResultFactory::class + )->disableOriginalConstructor( + )->getMock(); $context->expects($this->once()) ->method('getResultFactory') ->will($this->returnValue($this->resultFactory)); - $this->_controller = new \Magento\Contact\Controller\Index\Index( + $this->controller = new \Magento\Contact\Controller\Index\Index( $context, - $this->getMock(\Magento\Framework\Mail\Template\TransportBuilder::class, [], [], '', false), - $this->getMockForAbstractClass(\Magento\Framework\Translate\Inline\StateInterface::class, [], '', false), - $this->_scopeConfig, - $this->getMockForAbstractClass(\Magento\Store\Model\StoreManagerInterface::class, [], '', false) + $this->configMock ); } @@ -99,6 +85,6 @@ public function testExecute() ->with(ResultFactory::TYPE_PAGE) ->willReturn($resultStub); - $this->assertSame($resultStub, $this->_controller->execute()); + $this->assertSame($resultStub, $this->controller->execute()); } } diff --git a/app/code/Magento/Contact/Test/Unit/Controller/Index/PostTest.php b/app/code/Magento/Contact/Test/Unit/Controller/Index/PostTest.php index a65302733ddff..8fd54170819f5 100644 --- a/app/code/Magento/Contact/Test/Unit/Controller/Index/PostTest.php +++ b/app/code/Magento/Contact/Test/Unit/Controller/Index/PostTest.php @@ -6,6 +6,10 @@ */ namespace Magento\Contact\Test\Unit\Controller\Index; +use Magento\Contact\Model\ConfigInterface; +use Magento\Contact\Model\MailInterface; +use Magento\Framework\Controller\Result\Redirect; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -14,69 +18,60 @@ class PostTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Contact\Controller\Index\Index */ - protected $controller; - - /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $scopeConfigMock; - - /** - * @var \Magento\Framework\App\ViewInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $viewMock; + private $controller; /** - * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $urlMock; + private $configMock; /** - * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Controller\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $requestMock; + private $redirectResultFactoryMock; /** - * @var \Magento\Framework\App\Response\RedirectInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Redirect|\PHPUnit_Framework_MockObject_MockObject */ - protected $redirectMock; + private $redirectResultMock; /** - * @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $transportBuilderMock; + private $urlMock; /** - * @var \Magento\Framework\Translate\Inline\StateInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\Request\HttpRequest|\PHPUnit_Framework_MockObject_MockObject */ - protected $inlineTranslationMock; + private $requestStub; /** * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $messageManagerMock; + private $messageManagerMock; /** * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $storeManagerMock; + private $storeManagerMock; /** * @var \Magento\Framework\App\Request\DataPersistorInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $dataPersistorMock; + private $dataPersistorMock; + + /** + * @var MailInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $mailMock; protected function setUp() { - $this->scopeConfigMock = $this->getMockForAbstractClass( - \Magento\Framework\App\Config\ScopeConfigInterface::class, - ['isSetFlag'], - '', - false - ); + $this->mailMock = $this->getMockBuilder(MailInterface::class)->getMockForAbstractClass(); + $this->configMock = $this->getMockBuilder(ConfigInterface::class)->getMockForAbstractClass(); $context = $this->getMock( \Magento\Framework\App\Action\Context::class, - ['getRequest', 'getResponse', 'getView', 'getUrl', 'getRedirect', 'getMessageManager'], + ['getRequest', 'getResponse', 'getResultRedirectFactory', 'getUrl', 'getRedirect', 'getMessageManager'], [], '', false @@ -84,31 +79,37 @@ protected function setUp() $this->urlMock = $this->getMock(\Magento\Framework\UrlInterface::class, [], [], '', false); $this->messageManagerMock = $this->getMock(\Magento\Framework\Message\ManagerInterface::class, [], [], '', false); - $this->requestMock = - $this->getMock(\Magento\Framework\App\Request\Http::class, ['getPostValue'], [], '', false); - $this->redirectMock = - $this->getMock(\Magento\Framework\App\Response\RedirectInterface::class, [], [], '', false); - $this->viewMock = $this->getMock(\Magento\Framework\App\ViewInterface::class, [], [], '', false); - $this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class, [], [], '', false); - $this->transportBuilderMock = $this->getMock( - \Magento\Framework\Mail\Template\TransportBuilder::class, - [], + $this->requestStub = $this->getMock( + \Magento\Framework\App\Request\Http::class, + ['getPostValue', 'getParams', 'getParam'], [], '', false ); - $this->inlineTranslationMock = $this->getMock( - \Magento\Framework\Translate\Inline\StateInterface::class, + $this->redirectResultMock = $this->getMock( + \Magento\Framework\Controller\Result\Redirect::class, [], [], '', false ); + $this->redirectResultMock->method('setPath')->willReturnSelf(); + $this->redirectResultFactoryMock = $this->getMock( + \Magento\Framework\Controller\Result\RedirectFactory::class, + ['create'], + [], + '', + false + ); + $this->redirectResultFactoryMock + ->method('create') + ->willReturn($this->redirectResultMock); + $this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class, [], [], '', false); $this->dataPersistorMock = $this->getMockBuilder(\Magento\Framework\App\Request\DataPersistorInterface::class) ->getMockForAbstractClass(); $context->expects($this->any()) ->method('getRequest') - ->willReturn($this->requestMock); + ->willReturn($this->requestStub); $context->expects($this->any()) ->method('getResponse') @@ -122,38 +123,22 @@ protected function setUp() ->method('getUrl') ->willReturn($this->urlMock); - $context->expects($this->any()) - ->method('getRedirect') - ->willReturn($this->redirectMock); - $context->expects($this->once()) - ->method('getView') - ->willReturn($this->viewMock); - - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->controller = $objectManagerHelper->getObject( - \Magento\Contact\Controller\Index\Post::class, - [ - 'context' => $context, - 'transportBuilder' => $this->transportBuilderMock, - 'inlineTranslation' => $this->inlineTranslationMock, - 'scopeConfig' => $this->scopeConfigMock, - 'storeManager' => $this->storeManagerMock - ] - ); - $objectManagerHelper->setBackwardCompatibleProperty( - $this->controller, - 'dataPersistor', + ->method('getResultRedirectFactory') + ->willReturn($this->redirectResultFactoryMock); + + $this->controller = new \Magento\Contact\Controller\Index\Post( + $context, + $this->mailMock, + $this->configMock, $this->dataPersistorMock ); } public function testExecuteEmptyPost() { - $this->requestMock->expects($this->once())->method('getPostValue')->willReturn([]); - $this->redirectMock->expects($this->once())->method('redirect'); - $this->controller->execute(); + $this->stubRequestPostData([]); + $this->assertSame($this->redirectResultMock, $this->controller->execute()); } /** @@ -161,22 +146,15 @@ public function testExecuteEmptyPost() */ public function testExecutePostValidation($postData, $exceptionExpected) { - $this->requestMock->expects($this->any()) - ->method('getPostValue') - ->willReturn($postData); + $this->stubRequestPostData($postData); if ($exceptionExpected) { $this->messageManagerMock->expects($this->once()) - ->method('addError'); + ->method('addErrorMessage'); $this->dataPersistorMock->expects($this->once()) ->method('set') ->with('contact_us', $postData); } - $this->inlineTranslationMock->expects($this->once()) - ->method('resume'); - - $this->inlineTranslationMock->expects($this->once()) - ->method('suspend'); $this->controller->execute(); } @@ -201,54 +179,22 @@ public function testExecuteValidPost() ->method('clear') ->with('contact_us'); - $this->requestMock->expects($this->any()) - ->method('getPostValue') - ->willReturn($post); - - $transport = $this->getMock(\Magento\Framework\Mail\TransportInterface::class, [], [], '', false); - - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateIdentifier') - ->will($this->returnSelf()); - - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateOptions') - ->with([ - 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE, - 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, - ]) - ->will($this->returnSelf()); - - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateVars') - ->will($this->returnSelf()); - - $this->transportBuilderMock->expects($this->once()) - ->method('setFrom') - ->will($this->returnSelf()); - - $this->transportBuilderMock->expects($this->once()) - ->method('addTo') - ->will($this->returnSelf()); - - $this->transportBuilderMock->expects($this->once()) - ->method('setReplyTo') - ->with($post['email']) - ->will($this->returnSelf()); - - $this->transportBuilderMock->expects($this->once()) - ->method('getTransport') - ->willReturn($transport); - - $transport->expects($this->once()) - ->method('sendMessage'); - - $this->inlineTranslationMock->expects($this->once()) - ->method('resume'); - - $this->inlineTranslationMock->expects($this->once()) - ->method('suspend'); + $this->stubRequestPostData($post); $this->controller->execute(); } + + /** + * @param array $post + */ + private function stubRequestPostData($post) + { + $this->requestStub->method('getPostValue')->willReturn($post); + $this->requestStub->method('getParams')->willReturn($post); + $this->requestStub->method('getParam')->willReturnCallback( + function ($key) use ($post) { + return $post[$key]; + } + ); + } } diff --git a/app/code/Magento/Contact/Test/Unit/Controller/IndexTest.php b/app/code/Magento/Contact/Test/Unit/Controller/IndexTest.php index 723a054e2d252..317b9ab672b20 100644 --- a/app/code/Magento/Contact/Test/Unit/Controller/IndexTest.php +++ b/app/code/Magento/Contact/Test/Unit/Controller/IndexTest.php @@ -6,6 +6,10 @@ namespace Magento\Contact\Test\Unit\Controller; +use Magento\Contact\Model\ConfigInterface; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\ResponseInterface; + class IndexTest extends \PHPUnit_Framework_TestCase { /** @@ -13,36 +17,31 @@ class IndexTest extends \PHPUnit_Framework_TestCase * * @var \Magento\Contact\Controller\Index */ - protected $_controller; + private $controller; /** - * Scope config instance + * Module config instance * - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $_scopeConfig; + private $configMock; protected function setUp() { - $this->_scopeConfig = $this->getMockForAbstractClass( - \Magento\Framework\App\Config\ScopeConfigInterface::class, - ['isSetFlag'], - '', - false - ); - $context = $this->getMock( - \Magento\Framework\App\Action\Context::class, - ['getRequest', 'getResponse'], - [], - '', - false - ); + $this->configMock = $this->getMockBuilder(ConfigInterface::class)->getMockForAbstractClass(); + + $context = $this->getMockBuilder( + \Magento\Framework\App\Action\Context::class + )->setMethods( + ['getRequest', 'getResponse'] + )->disableOriginalConstructor( + )->getMock(); $context->expects($this->any()) ->method('getRequest') ->will( $this->returnValue( - $this->getMockForAbstractClass(\Magento\Framework\App\RequestInterface::class, [], '', false) + $this->getMockBuilder(RequestInterface::class)->getMockForAbstractClass() ) ); @@ -50,16 +49,13 @@ protected function setUp() ->method('getResponse') ->will( $this->returnValue( - $this->getMockForAbstractClass(\Magento\Framework\App\ResponseInterface::class, [], '', false) + $this->getMockBuilder(ResponseInterface::class)->getMockForAbstractClass() ) ); - $this->_controller = new \Magento\Contact\Test\Unit\Controller\Stub\IndexStub( + $this->controller = new \Magento\Contact\Test\Unit\Controller\Stub\IndexStub( $context, - $this->getMock(\Magento\Framework\Mail\Template\TransportBuilder::class, [], [], '', false), - $this->getMockForAbstractClass(\Magento\Framework\Translate\Inline\StateInterface::class, [], '', false), - $this->_scopeConfig, - $this->getMockForAbstractClass(\Magento\Store\Model\StoreManagerInterface::class, [], '', false) + $this->configMock ); } @@ -70,16 +66,10 @@ protected function setUp() */ public function testDispatch() { - $this->_scopeConfig->expects($this->once()) - ->method('isSetFlag') - ->with( - \Magento\Contact\Controller\Index::XML_PATH_ENABLED, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) - ->will($this->returnValue(false)); + $this->configMock->method('isEnabled')->willReturn(false); - $this->_controller->dispatch( - $this->getMockForAbstractClass(\Magento\Framework\App\RequestInterface::class, [], '', false) + $this->controller->dispatch( + $this->getMockBuilder(RequestInterface::class)->getMockForAbstractClass() ); } } diff --git a/app/code/Magento/Contact/Test/Unit/Model/MailTest.php b/app/code/Magento/Contact/Test/Unit/Model/MailTest.php new file mode 100644 index 0000000000000..de115920062eb --- /dev/null +++ b/app/code/Magento/Contact/Test/Unit/Model/MailTest.php @@ -0,0 +1,112 @@ +configMock = $this->getMockBuilder(ConfigInterface::class)->getMockForAbstractClass(); + $this->urlMock = $this->getMock(\Magento\Framework\UrlInterface::class, [], [], '', false); + $this->transportBuilderMock = $this->getMockBuilder( + \Magento\Framework\Mail\Template\TransportBuilder::class + )->disableOriginalConstructor( + )->getMock(); + $this->inlineTranslationMock = $this->getMockBuilder( + \Magento\Framework\Translate\Inline\StateInterface::class + )->disableOriginalConstructor( + )->getMock(); + + $this->mail = new Mail( + $this->configMock, + $this->transportBuilderMock, + $this->inlineTranslationMock + ); + } + + public function testSendMail() + { + $email = 'reply-to@example.com'; + $templateVars = ['comment' => 'Comment']; + + $transport = $this->getMock(\Magento\Framework\Mail\TransportInterface::class, [], [], '', false); + + $this->transportBuilderMock->expects($this->once()) + ->method('setTemplateIdentifier') + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setTemplateOptions') + ->with([ + 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE, + 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, + ]) + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setTemplateVars') + ->with($templateVars) + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setFrom') + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('addTo') + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setReplyTo') + ->with($email) + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('getTransport') + ->willReturn($transport); + + $transport->expects($this->once()) + ->method('sendMessage'); + + $this->inlineTranslationMock->expects($this->once()) + ->method('resume'); + + $this->inlineTranslationMock->expects($this->once()) + ->method('suspend'); + + $this->mail->send($email, $templateVars); + } +} diff --git a/app/code/Magento/Contact/etc/di.xml b/app/code/Magento/Contact/etc/di.xml index 0800e42b0ec0c..c70bcfd3e2ae8 100644 --- a/app/code/Magento/Contact/etc/di.xml +++ b/app/code/Magento/Contact/etc/di.xml @@ -6,6 +6,8 @@ */ --> + + diff --git a/app/code/Magento/Contact/i18n/en_US.csv b/app/code/Magento/Contact/i18n/en_US.csv index 7d42624e2f7e2..7b6a3011d714c 100644 --- a/app/code/Magento/Contact/i18n/en_US.csv +++ b/app/code/Magento/Contact/i18n/en_US.csv @@ -22,3 +22,6 @@ Contacts,Contacts "Email Sender","Email Sender" "Email Template","Email Template" "Email template chosen based on theme fallback when ""Default"" option is selected.","Email template chosen based on theme fallback when ""Default"" option is selected." +"Comment is missing","Comment is missing" +"Name is missing","Name is missing" +"Invalid email address","Invalid email address" \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php index ab2d1f73ff837..f68f2281e2854 100644 --- a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php @@ -21,6 +21,7 @@ public function testPostAction() $this->getRequest()->setPostValue($params); $this->dispatch('contact/index/post'); + $this->assertRedirect($this->stringContains('contact/index')); $this->assertSessionMessages( $this->contains( "Thanks for contacting us with your comments and questions. We'll respond to you very soon." @@ -28,4 +29,53 @@ public function testPostAction() \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS ); } + + /** + * @dataProvider dataInvalidPostAction + * @param $params + * @param $expectedMessage + */ + public function testInvalidPostAction($params, $expectedMessage) + { + $this->getRequest()->setPostValue($params); + + $this->dispatch('contact/index/post'); + $this->assertRedirect($this->stringContains('contact/index')); + $this->assertSessionMessages( + $this->contains($expectedMessage), + \Magento\Framework\Message\MessageInterface::TYPE_ERROR + ); + } + public static function dataInvalidPostAction() + { + return [ + 'missing_comment' => [ + 'params' => [ + 'name' => 'customer name', + 'comment' => '', + 'email' => 'user@example.com', + 'hideit' => '', + ], + 'expectedMessage' => "Comment is missing", + ], + 'missing_name' => [ + 'params' => [ + 'name' => '', + 'comment' => 'customer comment', + 'email' => 'user@example.com', + 'hideit' => '', + ], + 'expectedMessage' => "Name is missing", + ], + 'invalid_email' => [ + 'params' => [ + 'name' => 'customer name', + 'comment' => 'customer comment', + 'email' => 'invalidemail', + 'hideit' => '', + ], + 'expectedMessage' => "Invalid email address", + ], + ]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Contact/Model/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Contact/Model/ConfigTest.php new file mode 100644 index 0000000000000..deeb2957ec7e8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Contact/Model/ConfigTest.php @@ -0,0 +1,43 @@ +configModel = Bootstrap::getObjectManager()->create(\Magento\Contact\Model\ConfigInterface::class); + } + + /** + * @magentoAppArea frontend + * @magentoAppIsolation enabled + * @magentoConfigFixture current_store contact/contact/enabled 1 + */ + public function testIsEnabled() + { + $this->assertTrue($this->configModel->isEnabled()); + } + + /** + * @magentoAppArea frontend + * @magentoAppIsolation enabled + * @magentoConfigFixture current_store contact/contact/enabled 0 + */ + public function testIsNotEnabled() + { + $this->assertFalse($this->configModel->isEnabled()); + } +}