TopmenuTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Theme\Test\Unit\Block\Html;
  7. use Magento\Framework\Data\Tree\NodeFactory;
  8. use Magento\Framework\Data\TreeFactory;
  9. use Magento\Framework\Registry;
  10. use Magento\Framework\View\Element\Template\Context;
  11. use Magento\Theme\Block\Html\Topmenu;
  12. /**
  13. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  14. */
  15. class TopmenuTest extends \PHPUnit\Framework\TestCase
  16. {
  17. /**
  18. * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
  19. */
  20. protected $urlBuilder;
  21. /**
  22. * @var Registry|\PHPUnit_Framework_MockObject_MockObject
  23. */
  24. protected $registry;
  25. /**
  26. * @var Context|\PHPUnit_Framework_MockObject_MockObject
  27. */
  28. protected $context;
  29. /**
  30. * @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject
  31. */
  32. protected $nodeFactory;
  33. /**
  34. * @var TreeFactory|\PHPUnit_Framework_MockObject_MockObject
  35. */
  36. protected $treeFactory;
  37. /**
  38. * @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject
  39. */
  40. protected $category;
  41. /**
  42. * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
  43. */
  44. protected $storeManager;
  45. /**
  46. * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
  47. */
  48. private $eventManagerMock;
  49. /**
  50. * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
  51. */
  52. private $requestMock;
  53. // @codingStandardsIgnoreStart
  54. /** @var string */
  55. protected $htmlWithoutCategory = <<<HTML
  56. <li class="level0 nav-1 first"><a href="http://magento2/category-0.html" ><span></span></a></li><li class="level0 nav-2"><a href="http://magento2/category-1.html" ><span></span></a></li><li class="level0 nav-3"><a href="http://magento2/category-2.html" ><span></span></a></li><li class="level0 nav-4"><a href="http://magento2/category-3.html" ><span></span></a></li><li class="level0 nav-5"><a href="http://magento2/category-4.html" ><span></span></a></li><li class="level0 nav-6"><a href="http://magento2/category-5.html" ><span></span></a></li><li class="level0 nav-7"><a href="http://magento2/category-6.html" ><span></span></a></li><li class="level0 nav-8"><a href="http://magento2/category-7.html" ><span></span></a></li><li class="level0 nav-9"><a href="http://magento2/category-8.html" ><span></span></a></li><li class="level0 nav-10 last"><a href="http://magento2/category-9.html" ><span></span></a></li>
  57. HTML;
  58. /** @var string */
  59. protected $htmlWithCategory = <<<HTML
  60. <li class="level0 nav-1 first active"><a href="http://magento2/category-0.html" ><span></span></a></li><li class="level0 nav-2"><a href="http://magento2/category-1.html" ><span></span></a></li><li class="level0 nav-3"><a href="http://magento2/category-2.html" ><span></span></a></li><li class="level0 nav-4"><a href="http://magento2/category-3.html" ><span></span></a></li><li class="level0 nav-5"><a href="http://magento2/category-4.html" ><span></span></a></li><li class="level0 nav-6"><a href="http://magento2/category-5.html" ><span></span></a></li><li class="level0 nav-7"><a href="http://magento2/category-6.html" ><span></span></a></li><li class="level0 nav-8"><a href="http://magento2/category-7.html" ><span></span></a></li><li class="level0 nav-9"><a href="http://magento2/category-8.html" ><span></span></a></li><li class="level0 nav-10 last"><a href="http://magento2/category-9.html" ><span></span></a></li>
  61. HTML;
  62. // @codingStandardsIgnoreEnd
  63. protected function setUp()
  64. {
  65. $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
  66. ->getMockForAbstractClass();
  67. $this->urlBuilder = $this->getMockBuilder(\Magento\Framework\UrlInterface::class)
  68. ->getMockForAbstractClass();
  69. $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class)
  70. ->getMockForAbstractClass();
  71. $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
  72. ->getMockForAbstractClass();
  73. $this->nodeFactory = $this->getMockBuilder(\Magento\Framework\Data\Tree\NodeFactory::class)
  74. ->disableOriginalConstructor()
  75. ->getMock();
  76. $this->treeFactory = $this->getMockBuilder(\Magento\Framework\Data\TreeFactory::class)
  77. ->disableOriginalConstructor()
  78. ->getMock();
  79. $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
  80. $this->context = $objectManager->getObject(
  81. \Magento\Framework\View\Element\Template\Context::class,
  82. [
  83. 'urlBuilder' => $this->urlBuilder,
  84. 'storeManager' => $this->storeManager,
  85. 'eventManager' => $this->eventManagerMock,
  86. 'request' => $this->requestMock,
  87. ]
  88. );
  89. }
  90. /**
  91. * @return Topmenu
  92. */
  93. protected function getTopmenu()
  94. {
  95. return new Topmenu($this->context, $this->nodeFactory, $this->treeFactory);
  96. }
  97. public function testGetHtmlWithoutSelectedCategory()
  98. {
  99. $topmenuBlock = $this->getTopmenu();
  100. $treeNode = $this->buildTree(false);
  101. $transportObject = new \Magento\Framework\DataObject(['html' => $this->htmlWithoutCategory]);
  102. $this->eventManagerMock->expects($this->exactly(2))
  103. ->method('dispatch')
  104. ->willReturnMap([
  105. [
  106. 'page_block_html_topmenu_gethtml_before',
  107. [
  108. 'menu' => $treeNode,
  109. 'block' => $topmenuBlock,
  110. 'request' => $this->requestMock,
  111. ],
  112. $this->eventManagerMock
  113. ],
  114. [
  115. 'page_block_html_topmenu_gethtml_after',
  116. [
  117. 'menu' => $treeNode,
  118. 'transportObject' => $transportObject,
  119. ],
  120. $this->eventManagerMock
  121. ],
  122. ]);
  123. $this->assertEquals($this->htmlWithoutCategory, $topmenuBlock->getHtml());
  124. }
  125. public function testGetHtmlWithSelectedCategory()
  126. {
  127. $topmenuBlock = $this->getTopmenu();
  128. $treeNode = $this->buildTree(true);
  129. $transportObject = new \Magento\Framework\DataObject(['html' => $this->htmlWithCategory]);
  130. $this->eventManagerMock->expects($this->exactly(2))
  131. ->method('dispatch')
  132. ->willReturnMap([
  133. [
  134. 'page_block_html_topmenu_gethtml_before',
  135. [
  136. 'menu' => $treeNode,
  137. 'block' => $topmenuBlock,
  138. 'request' => $this->requestMock,
  139. ],
  140. $this->eventManagerMock
  141. ],
  142. [
  143. 'page_block_html_topmenu_gethtml_after',
  144. [
  145. 'menu' => $treeNode,
  146. 'transportObject' => $transportObject,
  147. ],
  148. $this->eventManagerMock
  149. ],
  150. ]);
  151. $this->assertEquals($this->htmlWithCategory, $topmenuBlock->getHtml());
  152. }
  153. public function testGetCacheKeyInfo()
  154. {
  155. $nodeFactory = $this->createMock(\Magento\Framework\Data\Tree\NodeFactory::class);
  156. $treeFactory = $this->createMock(\Magento\Framework\Data\TreeFactory::class);
  157. $topmenu = new Topmenu($this->context, $nodeFactory, $treeFactory);
  158. $this->urlBuilder->expects($this->once())->method('getBaseUrl')->willReturn('baseUrl');
  159. $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)
  160. ->disableOriginalConstructor()
  161. ->setMethods(['getCode'])
  162. ->getMock();
  163. $store->expects($this->once())->method('getCode')->willReturn('321');
  164. $this->storeManager->expects($this->once())->method('getStore')->willReturn($store);
  165. $this->assertEquals(
  166. ['BLOCK_TPL', '321', null, 'base_url' => 'baseUrl', 'template' => null],
  167. $topmenu->getCacheKeyInfo()
  168. );
  169. }
  170. /**
  171. * Create Tree Node mock object
  172. *
  173. * Helper method, that provides unified logic of creation of Tree Node mock objects.
  174. *
  175. * @param bool $isCurrentItem
  176. * @return \PHPUnit_Framework_MockObject_MockObject
  177. */
  178. private function buildTree($isCurrentItem)
  179. {
  180. $treeMock = $this->getMockBuilder(\Magento\Framework\Data\Tree::class)
  181. ->disableOriginalConstructor()
  182. ->getMock();
  183. $container = $this->createMock(\Magento\Catalog\Model\ResourceModel\Category\Tree::class);
  184. $children = $this->getMockBuilder(\Magento\Framework\Data\Tree\Node\Collection::class)
  185. ->setMethods(['count'])
  186. ->setConstructorArgs(['container' => $container])
  187. ->getMock();
  188. for ($i = 0; $i < 10; $i++) {
  189. $id = "category-node-$i";
  190. $categoryNode = $this->createPartialMock(
  191. \Magento\Framework\Data\Tree\Node::class,
  192. ['getId', 'hasChildren']
  193. );
  194. $categoryNode->expects($this->once())->method('getId')->willReturn($id);
  195. $categoryNode->expects($this->atLeastOnce())->method('hasChildren')->willReturn(false);
  196. $categoryNode->setData(
  197. [
  198. 'name' => "Category $i",
  199. 'id' => $id,
  200. 'url' => "http://magento2/category-$i.html",
  201. 'is_active' => $i == 0 ? $isCurrentItem : false,
  202. 'is_current_item' => $i == 0 ? $isCurrentItem : false,
  203. ]
  204. );
  205. $children->add($categoryNode);
  206. }
  207. $children->expects($this->once())->method('count')->willReturn(10);
  208. $nodeMock = $this->getMockBuilder(\Magento\Framework\Data\Tree\Node::class)
  209. ->disableOriginalConstructor()
  210. ->setMethods(['getChildren', '__call'])
  211. ->getMock();
  212. $nodeMock->expects($this->once())
  213. ->method('getChildren')
  214. ->willReturn($children);
  215. $nodeMock->expects($this->at(0))
  216. ->method('__call')
  217. ->with('setOutermostClass')
  218. ->willReturn(null);
  219. $nodeMock->expects($this->at(3))
  220. ->method('__call')
  221. ->with('getLevel', [])
  222. ->willReturn(null);
  223. $nodeMockData = [
  224. 'data' => [],
  225. 'idField' => 'root',
  226. 'tree' => $treeMock,
  227. ];
  228. $this->nodeFactory->expects($this->any())
  229. ->method('create')
  230. ->with($nodeMockData)
  231. ->willReturn($nodeMock);
  232. $this->treeFactory->expects($this->once())
  233. ->method('create')
  234. ->willReturn($treeMock);
  235. return $nodeMock;
  236. }
  237. public function testGetMenu()
  238. {
  239. $treeMock = $this->getMockBuilder(\Magento\Framework\Data\Tree::class)
  240. ->disableOriginalConstructor()
  241. ->getMock();
  242. $nodeMockData = [
  243. 'data' => [],
  244. 'idField' => 'root',
  245. 'tree' => $treeMock,
  246. ];
  247. $nodeMock = $this->getMockBuilder(\Magento\Framework\Data\Tree\Node::class)
  248. ->disableOriginalConstructor()
  249. ->getMock();
  250. $this->nodeFactory->expects($this->any())
  251. ->method('create')
  252. ->with($nodeMockData)
  253. ->willReturn($nodeMock);
  254. $this->treeFactory->expects($this->once())
  255. ->method('create')
  256. ->willReturn($treeMock);
  257. $topmenuBlock = $this->getTopmenu();
  258. $this->assertEquals($nodeMock, $topmenuBlock->getMenu());
  259. }
  260. }