Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MUI controller lacks JSON response, instead returns status 200 with empty body #19859

12 changes: 12 additions & 0 deletions app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ public function execute()

$contentType = $this->contentTypeResolver->resolve($component->getContext());
$this->getResponse()->setHeader('Content-Type', $contentType, true);
} else {
/** @var \Magento\Framework\Controller\Result\Json $resultJson */
$resultJson = $this->resultJsonFactory->create();
$resultJson->setStatusHeader(
\Zend\Http\Response::STATUS_CODE_403,
\Zend\Http\AbstractMessage::VERSION_11,
'Forbidden'
);
return $resultJson->setData([
'error' => $this->escaper->escapeHtml('Forbidden'),
'errorcode' => 403
]);
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->logger->critical($e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Ui\Test\Unit\Controller\Adminhtml\Index;

use Magento\Framework\Controller\Result\Json;
use Magento\Framework\Escaper;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Ui\Controller\Adminhtml\Index\Render;
use Magento\Ui\Model\UiComponentTypeResolver;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
use Zend\Http\AbstractMessage;
use Zend\Http\Response;

/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
Expand Down Expand Up @@ -97,6 +102,11 @@ class RenderTest extends \PHPUnit\Framework\TestCase
*/
private $loggerMock;

/**
* @var Escaper|\PHPUnit_Framework_MockObject_MockObject
*/
private $escaperMock;

protected function setUp()
{
$this->requestMock = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class)
Expand Down Expand Up @@ -170,6 +180,10 @@ protected function setUp()
$this->uiComponentTypeResolverMock = $this->getMockBuilder(UiComponentTypeResolver::class)
->disableOriginalConstructor()
->getMock();
$this->escaperMock = $this->createMock(Escaper::class);
$this->escaperMock->expects($this->any())
->method('escapeHtml')
->willReturnArgument(0);

$this->objectManagerHelper = new ObjectManagerHelper($this);

Expand All @@ -181,6 +195,7 @@ protected function setUp()
'contentTypeResolver' => $this->uiComponentTypeResolverMock,
'resultJsonFactory' => $this->resultJsonFactoryMock,
'logger' => $this->loggerMock,
'escaper' => $this->escaperMock,
]
);
}
Expand All @@ -201,7 +216,7 @@ public function testExecuteAjaxRequestException()
->method('appendBody')
->willThrowException(new \Exception('exception'));

$jsonResultMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class)
$jsonResultMock = $this->getMockBuilder(Json::class)
->disableOriginalConstructor()
->setMethods(['setData'])
->getMock();
Expand Down Expand Up @@ -290,6 +305,34 @@ public function testExecuteAjaxRequestWithoutPermissions(array $dataProviderConf
$name = 'test-name';
$renderedData = '<html>data</html>';

if (false === $isAllowed) {
$jsonResultMock = $this->getMockBuilder(Json::class)
->disableOriginalConstructor()
->setMethods(['setStatusHeader', 'setData'])
->getMock();

$jsonResultMock->expects($this->at(0))
->method('setStatusHeader')
->with(
Response::STATUS_CODE_403,
AbstractMessage::VERSION_11,
'Forbidden'
)
->willReturnSelf();

$jsonResultMock->expects($this->at(1))
->method('setData')
->with([
'error' => 'Forbidden',
'errorcode' => 403
])
->willReturnSelf();

$this->resultJsonFactoryMock->expects($this->any())
->method('create')
->willReturn($jsonResultMock);
}

$this->requestMock->expects($this->any())
->method('getParam')
->with('namespace')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
<block name="accessDeniedBlock" class="Magento\Backend\Test\Block\Denied" locator="#anchor-content" strategy="css selector" />
<block name="systemMessageDialog" class="Magento\AdminNotification\Test\Block\System\Messages" locator='.ui-popup-message .modal-inner-wrap' strategy="css selector" />
<block name="applicationVersion" class="Magento\Backend\Test\Block\Version" locator="body" strategy="css selector" />
<block name="modalMessage" class="Magento\Ui\Test\Block\Adminhtml\Modal" locator=".modal-popup>.modal-inner-wrap" strategy="css selector" />
</page>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Magento\Mtf\Client\BrowserInterface;
use Magento\Mtf\Constraint\AbstractConstraint;
use Magento\User\Test\Fixture\User;
use Magento\User\Test\TestStep\LoginUserOnBackendWithErrorStep;

/**
* Asserts that user has only related permissions.
Expand All @@ -18,6 +19,8 @@ class AssertUserRoleRestrictedAccess extends AbstractConstraint
{
const DENIED_ACCESS = 'Sorry, you need permissions to view this content.';

protected $loginStep = 'Magento\User\Test\TestStep\LoginUserOnBackendStep';

/**
* Asserts that user has only related permissions.
*
Expand All @@ -36,7 +39,7 @@ public function processAssert(
$denyUrl
) {
$this->objectManager->create(
\Magento\User\Test\TestStep\LoginUserOnBackendStep::class,
$this->loginStep,
['user' => $user]
)->run();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\User\Test\Constraint;

/**
* @inheritdoc
*/
class AssertUserRoleRestrictedAccessWithError extends AssertUserRoleRestrictedAccess
{
protected $loginStep = 'Magento\User\Test\TestStep\LoginUserOnBackendWithErrorStep';
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@
namespace Magento\User\Test\Constraint;

use Magento\Backend\Test\Page\Adminhtml\Dashboard;
use Magento\User\Test\Fixture\User;
use Magento\Mtf\Constraint\AbstractConstraint;
use Magento\User\Test\Fixture\User;
use Magento\User\Test\TestStep\LoginUserOnBackendStep;

/**
* Verify whether customer has logged in to the Backend.
*/
class AssertUserSuccessLogin extends AbstractConstraint
{
/**
* @var string
*/
protected $loginStep = LoginUserOnBackendStep::class;

/**
* Verify whether customer has logged in to the Backend.
*
Expand All @@ -25,7 +31,7 @@ class AssertUserSuccessLogin extends AbstractConstraint
public function processAssert(User $user, Dashboard $dashboard)
{
$this->objectManager->create(
\Magento\User\Test\TestStep\LoginUserOnBackendStep::class,
$this->loginStep,
['user' => $user]
)->run();
\PHPUnit\Framework\Assert::assertTrue(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\User\Test\Constraint;

use Magento\User\Test\TestStep\LoginUserOnBackendWithErrorStep;

/**
* Verify whether customer has logged in to the Backend with error alert.
*/
class AssertUserSuccessLoginWithError extends AssertUserSuccessLogin
{
/**
* @var string
*/
protected $loginStep = LoginUserOnBackendWithErrorStep::class;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<constraint name="Magento\User\Test\Constraint\AssertUserInGrid" />
<constraint name="Magento\User\Test\Constraint\AssertUserSuccessLogOut" />
<constraint name="Magento\User\Test\Constraint\AssertUserSuccessLogin" />
<constraint name="Magento\User\Test\Constraint\AssertUserRoleRestrictedAccess" />
<constraint name="Magento\User\Test\Constraint\AssertUserRoleRestrictedAccessWithError" />
</variation>
</testCase>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ public function testUpdateAdminUserRolesEntity(
*/
public function tearDown()
{
sleep(3);
$modalMessage = $this->dashboard->getModalMessage();
if ($modalMessage->isVisible()) {
$modalMessage->acceptAlert();
}
$this->dashboard->getAdminPanelHeader()->logOut();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
<constraint name="Magento\User\Test\Constraint\AssertRoleSuccessSaveMessage" />
<constraint name="Magento\User\Test\Constraint\AssertRoleInGrid" />
<constraint name="Magento\User\Test\Constraint\AssertUserSuccessLogOut" />
<constraint name="Magento\User\Test\Constraint\AssertUserSuccessLogin" />
<constraint name="Magento\User\Test\Constraint\AssertUserRoleRestrictedAccess" />
<constraint name="Magento\User\Test\Constraint\AssertUserSuccessLoginWithError"/>
<constraint name="Magento\User\Test\Constraint\AssertUserRoleRestrictedAccessWithError" />
</variation>
<variation name="UpdateAdminUserRoleEntityTestVariation3">
<data name="user/dataset" xsi:type="string">custom_admin_with_default_role</data>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\User\Test\TestStep;

use Magento\Backend\Test\Page\Adminhtml\Dashboard;
use Magento\Mtf\Client\BrowserInterface;
use Magento\Mtf\TestStep\TestStepInterface;

/**
* Close access error modal message.
*/
class CloseErrorAlertStep implements TestStepInterface
{
/**
* @var Dashboard
*/
private $dashboard;

/**
* @var BrowserInterface
*/
private $browser;

/**
* @param Dashboard $dashboard
* @param BrowserInterface $browser
*/
public function __construct(
Dashboard $dashboard,
BrowserInterface $browser
) {
$this->dashboard = $dashboard;
$this->browser = $browser;
}

/**
* @inheritdoc
*/
public function run()
{
$modalMessage = $this->dashboard->getModalMessage();
try {
$this->browser->waitUntil(
function () use ($modalMessage) {
return $modalMessage->isVisible() ? true : null;
}
);
$modalMessage->acceptAlert();
} catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
//There is no modal to accept.
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class LoginUserOnBackendStep implements TestStepInterface
*
* @var BrowserInterface
*/
private $browser;
protected $browser;

/**
* Array of error messages on admin login form.
Expand Down Expand Up @@ -108,8 +108,6 @@ public function run()
}
}
}

$this->dashboard->getSystemMessageDialog()->closePopup();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\User\Test\TestStep;

use Magento\Backend\Test\Page\AdminAuthLogin;
use Magento\Backend\Test\Page\Adminhtml\Dashboard;
use Magento\Mtf\Client\BrowserInterface;
use Magento\User\Test\Fixture\User;

/**
* Login user on backend with access error.
*/
class LoginUserOnBackendWithErrorStep extends LoginUserOnBackendStep
{
/**
* @var CloseErrorAlertStep
*/
private $closeErrorAlertStep;

/**
* @param LogoutUserOnBackendStep $logoutUserOnBackendStep
* @param AdminAuthLogin $adminAuth
* @param User $user
* @param Dashboard $dashboard
* @param BrowserInterface $browser
*/
public function __construct(
LogoutUserOnBackendStep $logoutUserOnBackendStep,
AdminAuthLogin $adminAuth,
User $user,
Dashboard $dashboard,
BrowserInterface $browser,
CloseErrorAlertStep $closeErrorAlertStep
) {
parent::__construct($logoutUserOnBackendStep, $adminAuth, $user, $dashboard, $browser);
$this->closeErrorAlertStep = $closeErrorAlertStep;
}

/**
* Run step flow.
*
* @return void
*/
public function run()
{
parent::run();
$this->closeErrorAlertStep->run();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public function __construct(AdminAuthLogin $adminAuth, Dashboard $dashboard)
public function run()
{
$this->adminAuth->open();
$this->dashboard->getSystemMessageDialog()->closePopup();
$this->dashboard->getAdminPanelHeader()->logOut();
}
}
Loading