magento2-docker/dev/tests/integration/testsuite/Magento/Framework/View/LayoutDirectivesTest.php

325 lines
12 KiB
PHP
Executable File

<?php
/**
* Set of tests of layout directives handling behavior
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\View;
use Magento\Framework\App\State;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class LayoutDirectivesTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Magento\Framework\View\LayoutFactory
*/
protected $layoutFactory;
/**
* @var \Magento\Framework\View\Layout\BuilderFactory
*/
protected $builderFactory;
/**
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $objectManager;
/**
* @var \Magento\Framework\App\State
*/
protected $state;
protected function setUp(): void
{
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
$this->layoutFactory = $this->objectManager->get(\Magento\Framework\View\LayoutFactory::class);
$this->state = $this->objectManager->get(\Magento\Framework\App\State::class);
}
/**
* Prepare a layout model with pre-loaded fixture of an update XML
*
* @param string $fixtureFile
* @return \Magento\Framework\View\LayoutInterface
*/
protected function _getLayoutModel($fixtureFile)
{
$this->objectManager->get(\Magento\Framework\App\Cache\Type\Layout::class)->clean();
$layout = $this->layoutFactory->create();
/** @var $xml \Magento\Framework\View\Layout\Element */
$xml = simplexml_load_file(
__DIR__ . "/_files/layout_directives_test/{$fixtureFile}",
\Magento\Framework\View\Layout\Element::class
);
$layout->loadString($xml->asXml());
$layout->generateElements();
return $layout;
}
/**
* Test scheduled operations in the rendering of elements
*
* Expected behavior:
* 1) block1 was not declared at the moment when "1" invocation declared. The operation is scheduled
* 2) block1 creation directive schedules adding "2" as well
* 3) block2 is generated with "3"
* 4) yet another action schedules replacing value of block2 into "4"
* 5) when entire layout is read, all scheduled operations are executed in the same order as declared
* (blocks are instantiated first, of course)
* The end result can be observed in container1
*
* @magentoAppIsolation enabled
*/
public function testRenderElement()
{
$layout = $this->_getLayoutModel('render.xml');
$this->assertEquals('124', $layout->renderElement('container_one'));
$this->assertEquals('12', $layout->renderElement('block_one'));
}
/**
* @magentoAppIsolation enabled
*/
public function testRenderNonExistentElementShouldThrowException()
{
$this->expectException(\OutOfBoundsException::class);
$layout = $this->_getLayoutModel('render.xml');
$this->assertEmpty($layout->renderElement('nonexisting_element'));
$this->expectExceptionMessage(
'The element with the "nonexisting_element" ID wasn\'t found. Verify the ID and try again.'
);
}
/**
* Invoke getBlock() while layout is being generated
*
* Assertions in this test are pure formalism. The point is to emulate situation where block refers to other block
* while the latter hasn't been generated yet, and assure that there is no crash
*/
public function testGetBlockUnscheduled()
{
$layout = $this->_getLayoutModel('get_block.xml');
$this->assertInstanceOf(\Magento\Framework\View\Element\Text::class, $layout->getBlock('block_first'));
$this->assertInstanceOf(\Magento\Framework\View\Element\Text::class, $layout->getBlock('block_second'));
}
public function testLayoutArgumentsDirective()
{
$layout = $this->_getLayoutModel('arguments.xml');
$this->assertEquals('1', $layout->getBlock('block_with_args')->getOne());
$this->assertEquals('two', $layout->getBlock('block_with_args')->getTwo());
$this->assertEquals('3', $layout->getBlock('block_with_args')->getThree());
}
public function testLayoutArgumentsDirectiveIfComplexValues()
{
$layout = $this->_getLayoutModel('arguments_complex_values.xml');
$this->assertEquals(
['parameters' => ['first' => '1', 'second' => '2']],
$layout->getBlock('block_with_args_complex_values')->getOne()
);
$this->assertEquals('two', $layout->getBlock('block_with_args_complex_values')->getTwo());
$this->assertEquals(
['extra' => ['key1' => 'value1', 'key2' => 'value2']],
$layout->getBlock('block_with_args_complex_values')->getThree()
);
}
public function testLayoutObjectArgumentsDirective()
{
$layout = $this->_getLayoutModel('arguments_object_type.xml');
$this->assertInstanceOf(
\Magento\Framework\Data\Collection::class,
$layout->getBlock('block_with_object_args')->getOne()
);
$this->assertInstanceOf(
\Magento\Framework\Data\Collection::class,
$layout->getBlock('block_with_object_args')->getTwo()
);
$this->assertEquals(3, $layout->getBlock('block_with_object_args')->getThree());
}
public function testLayoutUrlArgumentsDirective()
{
$layout = $this->_getLayoutModel('arguments_url_type.xml');
$this->assertStringContainsString('customer/account/login', $layout->getBlock('block_with_url_args')->getOne());
$this->assertStringContainsString(
'customer/account/logout',
$layout->getBlock('block_with_url_args')->getTwo()
);
$this->assertStringContainsString('customer_id/3', $layout->getBlock('block_with_url_args')->getTwo());
}
public function testLayoutObjectArgumentUpdatersDirective()
{
$this->markTestSkipped('Will be fixed after MAGETWO-33840 will be done');
$layout = $this->_getLayoutModel('arguments_object_type_updaters.xml');
$expectedObjectData = [0 => 'updater call', 1 => 'updater call'];
$expectedSimpleData = 1;
$dataSource = $layout->getBlock('block_with_object_updater_args')->getOne();
$this->assertInstanceOf(\Magento\Framework\Data\Collection::class, $dataSource);
$this->assertEquals($expectedObjectData, $dataSource->getUpdaterCall());
$this->assertEquals($expectedSimpleData, $layout->getBlock('block_with_object_updater_args')->getTwo());
}
/**
* @magentoAppIsolation enabled
*/
public function testMoveSameAlias()
{
$layout = $this->_getLayoutModel('move_the_same_alias.xml');
$this->assertEquals('container1', $layout->getParentName('no_name3'));
}
/**
* @magentoAppIsolation enabled
*/
public function testMoveNewAlias()
{
$layout = $this->_getLayoutModel('move_new_alias.xml');
$this->assertEquals('new_alias', $layout->getElementAlias('no_name3'));
}
public function testActionAnonymousParentBlock()
{
$layout = $this->_getLayoutModel('action_for_anonymous_parent_block.xml');
$this->assertEquals('schedule_block0', $layout->getParentName('test.block.insert'));
$this->assertEquals('schedule_block1', $layout->getParentName('test.block.append'));
}
/**
* @magentoAppIsolation enabled
*/
public function testRemove()
{
$layout = $this->_getLayoutModel('remove.xml');
$this->assertFalse($layout->getBlock('no_name2'));
$this->assertFalse($layout->getBlock('child_block1'));
$this->assertTrue($layout->isBlock('child_block2'));
}
/**
* @magentoAppIsolation enabled
*/
public function testRemoveCancellation()
{
$layout = $this->_getLayoutModel('remove_cancellation.xml');
$this->assertTrue($layout->isContainer('container1'));
$this->assertTrue($layout->isBlock('child_block1'));
$this->assertTrue($layout->isBlock('no_name2'));
$this->assertFalse($layout->getBlock('not_exist'));
}
/**
* @magentoAppIsolation enabled
*/
public function testMove()
{
$layout = $this->_getLayoutModel('move.xml');
$this->assertEquals('container2', $layout->getParentName('container1'));
$this->assertEquals('container1', $layout->getParentName('no.name2'));
$this->assertEquals('block_container', $layout->getParentName('no_name3'));
// verify `after` attribute
$this->assertEquals('block_container', $layout->getParentName('no_name'));
$childrenOrderArray = array_keys($layout->getChildBlocks($layout->getParentName('no_name')));
$positionAfter = array_search('child_block1', $childrenOrderArray);
$positionToVerify = array_search('no_name', $childrenOrderArray);
$this->assertEquals($positionAfter, --$positionToVerify);
// verify `before` attribute
$this->assertEquals('block_container', $layout->getParentName('no_name4'));
$childrenOrderArray = array_keys($layout->getChildBlocks($layout->getParentName('no_name4')));
$positionBefore = array_search('child_block2', $childrenOrderArray);
$positionToVerify = array_search('no_name4', $childrenOrderArray);
$this->assertEquals($positionBefore, ++$positionToVerify);
}
/**
*/
public function testMoveBroken()
{
$this->expectException(\Magento\Framework\Exception\LocalizedException::class);
$this->_getLayoutModel('move_broken.xml');
}
/**
*/
public function testMoveAliasBroken()
{
$this->expectException(\Magento\Framework\Exception\LocalizedException::class);
$this->_getLayoutModel('move_alias_broken.xml');
}
public function testRemoveBroken()
{
if ($this->state->getMode() === State::MODE_DEVELOPER) {
$this->expectException('OutOfBoundsException');
}
$this->_getLayoutModel('remove_broken.xml');
}
/**
* @param string $case
* @param string $expectedResult
* @dataProvider sortSpecialCasesDataProvider
* @magentoAppIsolation enabled
*/
public function testSortSpecialCases($case, $expectedResult)
{
$layout = $this->_getLayoutModel($case);
$this->assertEquals($expectedResult, $layout->renderElement('root'));
}
/**
* @return array
*/
public function sortSpecialCasesDataProvider()
{
return [
'Before element which is after' => ['sort_before_after.xml', '312'],
'Before element which is previous' => ['sort_before_before.xml', '213'],
'After element which is after' => ['sort_after_after.xml', '312'],
'After element which is previous' => ['sort_after_previous.xml', '321']
];
}
/**
* @magentoConfigFixture current_store true_options 1
* @magentoAppIsolation enabled
*/
public function testIfConfigForBlock()
{
$layout = $this->_getLayoutModel('ifconfig.xml');
$this->assertFalse($layout->getBlock('block1'));
$this->assertFalse($layout->getBlock('block2'));
$this->assertInstanceOf(\Magento\Framework\View\Element\BlockInterface::class, $layout->getBlock('block3'));
$this->assertFalse($layout->getBlock('block4'));
}
/**
* @magentoConfigFixture current_store true_options 1
* @magentoAppIsolation enabled
*/
public function testBlockGroups()
{
$layout = $this->_getLayoutModel('group.xml');
$childNames = $layout->getBlock('block1')->getGroupChildNames('group1');
$this->assertEquals(['block2', 'block3'], $childNames);
}
}