123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- /**
- * Abstract class for the controller tests
- */
- namespace Magento\TestFramework\TestCase;
- use Magento\Framework\Data\Form\FormKey;
- use Magento\Framework\Message\MessageInterface;
- use Magento\Framework\Stdlib\CookieManagerInterface;
- use Magento\Framework\View\Element\Message\InterpretationStrategyInterface;
- use Magento\Theme\Controller\Result\MessagePlugin;
- use Magento\Framework\App\Request\Http as HttpRequest;
- use Magento\Framework\App\Response\Http as HttpResponse;
- /**
- * @SuppressWarnings(PHPMD.NumberOfChildren)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- abstract class AbstractController extends \PHPUnit\Framework\TestCase
- {
- protected $_runCode = '';
- protected $_runScope = 'store';
- protected $_runOptions = [];
- /**
- * @var \Magento\Framework\App\RequestInterface
- */
- protected $_request;
- /**
- * @var \Magento\Framework\App\ResponseInterface
- */
- protected $_response;
- /**
- * @var \Magento\TestFramework\ObjectManager
- */
- protected $_objectManager;
- /**
- * Whether absence of session error messages has to be asserted automatically upon a test completion
- *
- * @var bool
- */
- protected $_assertSessionErrors = false;
- /**
- * Bootstrap instance getter
- *
- * @return \Magento\TestFramework\Helper\Bootstrap
- */
- protected function _getBootstrap()
- {
- return \Magento\TestFramework\Helper\Bootstrap::getInstance();
- }
- /**
- * Bootstrap application before any test
- */
- protected function setUp()
- {
- $this->_assertSessionErrors = false;
- $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
- $this->_objectManager->removeSharedInstance(\Magento\Framework\App\ResponseInterface::class);
- $this->_objectManager->removeSharedInstance(\Magento\Framework\App\RequestInterface::class);
- }
- /**
- * @inheritDoc
- */
- protected function tearDown()
- {
- $this->_request = null;
- $this->_response = null;
- $this->_objectManager = null;
- }
- /**
- * Ensure that there were no error messages displayed on the admin panel
- */
- protected function assertPostConditions()
- {
- if ($this->_assertSessionErrors) {
- // equalTo() is intentionally used instead of isEmpty() to provide the informative diff
- $this->assertSessionMessages(
- $this->equalTo([]),
- \Magento\Framework\Message\MessageInterface::TYPE_ERROR
- );
- }
- }
- /**
- * Run request
- *
- * @param string $uri
- */
- public function dispatch($uri)
- {
- /** @var HttpRequest $request */
- $request = $this->getRequest();
- $request->setRequestUri($uri);
- if ($request->isPost()
- && !array_key_exists('form_key', $request->getPost())
- ) {
- /** @var FormKey $formKey */
- $formKey = $this->_objectManager->get(FormKey::class);
- $request->setPostValue('form_key', $formKey->getFormKey());
- }
- $this->_getBootstrap()->runApp();
- }
- /**
- * Request getter
- *
- * @return \Magento\Framework\App\RequestInterface|HttpRequest
- */
- public function getRequest()
- {
- if (!$this->_request) {
- $this->_request = $this->_objectManager->get(\Magento\Framework\App\RequestInterface::class);
- }
- return $this->_request;
- }
- /**
- * Response getter
- *
- * @return \Magento\Framework\App\ResponseInterface|HttpResponse
- */
- public function getResponse()
- {
- if (!$this->_response) {
- $this->_response = $this->_objectManager->get(\Magento\Framework\App\ResponseInterface::class);
- }
- return $this->_response;
- }
- /**
- * Assert that response is '404 Not Found'
- */
- public function assert404NotFound()
- {
- $this->assertEquals('noroute', $this->getRequest()->getControllerName());
- $this->assertContains('404 Not Found', $this->getResponse()->getBody());
- }
- /**
- * Analyze response object and look for header with specified name, and assert a regex towards its value
- *
- * @param string $headerName
- * @param string $valueRegex
- * @throws \PHPUnit\Framework\AssertionFailedError when header not found
- */
- public function assertHeaderPcre($headerName, $valueRegex)
- {
- $headerFound = false;
- $headers = $this->getResponse()->getHeaders();
- foreach ($headers as $header) {
- if ($header->getFieldName() === $headerName) {
- $headerFound = true;
- $this->assertRegExp($valueRegex, $header->getFieldValue());
- }
- }
- if (!$headerFound) {
- $this->fail("Header '{$headerName}' was not found. Headers dump:\n" . var_export($headers, 1));
- }
- }
- /**
- * Assert that there is a redirect to expected URL.
- * Omit expected URL to check that redirect to wherever has been occurred.
- * Examples of usage:
- * $this->assertRedirect($this->equalTo($expectedUrl));
- * $this->assertRedirect($this->stringStartsWith($expectedUrlPrefix));
- * $this->assertRedirect($this->stringEndsWith($expectedUrlSuffix));
- * $this->assertRedirect($this->stringContains($expectedUrlSubstring));
- *
- * @param \PHPUnit\Framework\Constraint\Constraint|null $urlConstraint
- */
- public function assertRedirect(\PHPUnit\Framework\Constraint\Constraint $urlConstraint = null)
- {
- $this->assertTrue($this->getResponse()->isRedirect(), 'Redirect was expected, but none was performed.');
- if ($urlConstraint) {
- $actualUrl = '';
- foreach ($this->getResponse()->getHeaders() as $header) {
- if ($header->getFieldName() == 'Location') {
- $actualUrl = $header->getFieldValue();
- break;
- }
- }
- $this->assertThat($actualUrl, $urlConstraint, 'Redirection URL does not match expectations');
- }
- }
- /**
- * Assert that actual session messages meet expectations:
- * Usage examples:
- * $this->assertSessionMessages($this->isEmpty(), \Magento\Framework\Message\MessageInterface::TYPE_ERROR);
- * $this->assertSessionMessages($this->equalTo(['Entity has been saved.'],
- * \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS);
- *
- * @param \PHPUnit\Framework\Constraint\Constraint $constraint Constraint to compare actual messages against
- * @param string|null $messageType Message type filter,
- * one of the constants \Magento\Framework\Message\MessageInterface::*
- * @param string $messageManagerClass Class of the session model that manages messages
- */
- public function assertSessionMessages(
- \PHPUnit\Framework\Constraint\Constraint $constraint,
- $messageType = null,
- $messageManagerClass = \Magento\Framework\Message\Manager::class
- ) {
- $this->_assertSessionErrors = false;
- /** @var MessageInterface[]|string[] $messageObjects */
- $messages = $this->getMessages($messageType, $messageManagerClass);
- /** @var string[] $messages */
- $messagesFiltered = array_map(
- function ($message) {
- /** @var MessageInterface|string $message */
- return ($message instanceof MessageInterface) ? $message->toString() : $message;
- },
- $messages
- );
- $this->assertThat(
- $messagesFiltered,
- $constraint,
- 'Session messages do not meet expectations ' . var_export($messagesFiltered, true)
- );
- }
- /**
- * Return all stored messages
- *
- * @param string|null $messageType
- * @param string $messageManagerClass
- * @return array
- */
- protected function getMessages(
- $messageType = null,
- $messageManagerClass = \Magento\Framework\Message\Manager::class
- ) {
- return array_merge(
- $this->getSessionMessages($messageType, $messageManagerClass),
- $this->getCookieMessages($messageType)
- );
- }
- /**
- * Return messages stored in session
- *
- * @param string|null $messageType
- * @param string $messageManagerClass
- * @return array
- */
- protected function getSessionMessages(
- $messageType = null,
- $messageManagerClass = \Magento\Framework\Message\Manager::class
- ) {
- /** @var $messageManager \Magento\Framework\Message\ManagerInterface */
- $messageManager = $this->_objectManager->get($messageManagerClass);
- /** @var $messages \Magento\Framework\Message\AbstractMessage[] */
- if ($messageType === null) {
- $messages = $messageManager->getMessages()->getItems();
- } else {
- $messages = $messageManager->getMessages()->getItemsByType($messageType);
- }
- /** @var $messageManager InterpretationStrategyInterface */
- $interpretationStrategy = $this->_objectManager->get(InterpretationStrategyInterface::class);
- $actualMessages = [];
- foreach ($messages as $message) {
- $actualMessages[] = $interpretationStrategy->interpret($message);
- }
- return $actualMessages;
- }
- /**
- * Return messages stored in cookies by type
- *
- * @param string|null $messageType
- * @return array
- */
- protected function getCookieMessages($messageType = null)
- {
- /** @var $cookieManager CookieManagerInterface */
- $cookieManager = $this->_objectManager->get(CookieManagerInterface::class);
- /** @var $jsonSerializer \Magento\Framework\Serialize\Serializer\Json */
- $jsonSerializer = $this->_objectManager->get(\Magento\Framework\Serialize\Serializer\Json::class);
- try {
- $messages = $jsonSerializer->unserialize(
- $cookieManager->getCookie(
- MessagePlugin::MESSAGES_COOKIES_NAME,
- $jsonSerializer->serialize([])
- )
- );
- if (!is_array($messages)) {
- $messages = [];
- }
- } catch (\InvalidArgumentException $e) {
- $messages = [];
- }
- $actualMessages = [];
- foreach ($messages as $message) {
- if ($messageType === null || $message['type'] == $messageType) {
- $actualMessages[] = $message['text'];
- }
- }
- return $actualMessages;
- }
- }
|