BreadcrumbsHelperTest.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.3.6
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\View\Helper;
  16. use Cake\TestSuite\TestCase;
  17. use Cake\View\Helper\BreadcrumbsHelper;
  18. use Cake\View\View;
  19. class BreadcrumbsHelperTest extends TestCase
  20. {
  21. /**
  22. * Instance of the BreadcrumbsHelper
  23. *
  24. * @var BreadcrumbsHelper
  25. */
  26. public $breadcrumbs;
  27. /**
  28. * setUp method
  29. *
  30. * @return void
  31. */
  32. public function setUp()
  33. {
  34. parent::setUp();
  35. $view = new View();
  36. $this->breadcrumbs = new BreadcrumbsHelper($view);
  37. }
  38. /**
  39. * Test adding crumbs to the trail using add()
  40. *
  41. * @return void
  42. */
  43. public function testAdd()
  44. {
  45. $this->breadcrumbs
  46. ->add('Home', '/', ['class' => 'first'])
  47. ->add('Some text', ['controller' => 'Some', 'action' => 'text']);
  48. $result = $this->breadcrumbs->getCrumbs();
  49. $expected = [
  50. [
  51. 'title' => 'Home',
  52. 'url' => '/',
  53. 'options' => [
  54. 'class' => 'first',
  55. ],
  56. ],
  57. [
  58. 'title' => 'Some text',
  59. 'url' => [
  60. 'controller' => 'Some',
  61. 'action' => 'text',
  62. ],
  63. 'options' => [],
  64. ],
  65. ];
  66. $this->assertEquals($expected, $result);
  67. }
  68. /**
  69. * Test adding multiple crumbs at once to the trail using add()
  70. *
  71. * @return void
  72. */
  73. public function testAddMultiple()
  74. {
  75. $this->breadcrumbs
  76. ->add([
  77. [
  78. 'title' => 'Home',
  79. 'url' => '/',
  80. 'options' => ['class' => 'first'],
  81. ],
  82. [
  83. 'title' => 'Some text',
  84. 'url' => ['controller' => 'Some', 'action' => 'text'],
  85. ],
  86. [
  87. 'title' => 'Final',
  88. ],
  89. ]);
  90. $result = $this->breadcrumbs->getCrumbs();
  91. $expected = [
  92. [
  93. 'title' => 'Home',
  94. 'url' => '/',
  95. 'options' => [
  96. 'class' => 'first',
  97. ],
  98. ],
  99. [
  100. 'title' => 'Some text',
  101. 'url' => [
  102. 'controller' => 'Some',
  103. 'action' => 'text',
  104. ],
  105. 'options' => [],
  106. ],
  107. [
  108. 'title' => 'Final',
  109. 'url' => null,
  110. 'options' => [],
  111. ],
  112. ];
  113. $this->assertEquals($expected, $result);
  114. }
  115. /**
  116. * Test adding crumbs to the trail using prepend()
  117. *
  118. * @return void
  119. */
  120. public function testPrepend()
  121. {
  122. $this->breadcrumbs
  123. ->add('Home', '/', ['class' => 'first'])
  124. ->prepend('Some text', ['controller' => 'Some', 'action' => 'text'])
  125. ->prepend('The root', '/root', ['data-name' => 'some-name']);
  126. $result = $this->breadcrumbs->getCrumbs();
  127. $expected = [
  128. [
  129. 'title' => 'The root',
  130. 'url' => '/root',
  131. 'options' => ['data-name' => 'some-name'],
  132. ],
  133. [
  134. 'title' => 'Some text',
  135. 'url' => [
  136. 'controller' => 'Some',
  137. 'action' => 'text',
  138. ],
  139. 'options' => [],
  140. ],
  141. [
  142. 'title' => 'Home',
  143. 'url' => '/',
  144. 'options' => [
  145. 'class' => 'first',
  146. ],
  147. ],
  148. ];
  149. $this->assertEquals($expected, $result);
  150. }
  151. /**
  152. * Test adding crumbs to the trail using prepend()
  153. *
  154. * @return void
  155. */
  156. public function testPrependMultiple()
  157. {
  158. $this->breadcrumbs
  159. ->add('Home', '/', ['class' => 'first'])
  160. ->prepend([
  161. ['title' => 'Some text', 'url' => ['controller' => 'Some', 'action' => 'text']],
  162. ['title' => 'The root', 'url' => '/root', 'options' => ['data-name' => 'some-name']],
  163. ]);
  164. $result = $this->breadcrumbs->getCrumbs();
  165. $expected = [
  166. [
  167. 'title' => 'Some text',
  168. 'url' => [
  169. 'controller' => 'Some',
  170. 'action' => 'text',
  171. ],
  172. 'options' => [],
  173. ],
  174. [
  175. 'title' => 'The root',
  176. 'url' => '/root',
  177. 'options' => ['data-name' => 'some-name'],
  178. ],
  179. [
  180. 'title' => 'Home',
  181. 'url' => '/',
  182. 'options' => [
  183. 'class' => 'first',
  184. ],
  185. ],
  186. ];
  187. $this->assertEquals($expected, $result);
  188. }
  189. /**
  190. * Test ability to empty crumbs list.
  191. *
  192. * @return void
  193. */
  194. public function testReset()
  195. {
  196. $this->breadcrumbs->add('Home', '/');
  197. $this->breadcrumbs->add('Products', '/products');
  198. $crumbs = $this->breadcrumbs->getCrumbs();
  199. $this->assertEquals(count($crumbs), 2);
  200. $this->breadcrumbs->reset();
  201. $actual = $this->breadcrumbs->getCrumbs();
  202. $this->assertEquals($actual, []);
  203. }
  204. /**
  205. * Test adding crumbs to a specific index
  206. *
  207. * @return void
  208. */
  209. public function testInsertAt()
  210. {
  211. $this->breadcrumbs
  212. ->add('Home', '/', ['class' => 'first'])
  213. ->prepend('Some text', ['controller' => 'Some', 'action' => 'text'])
  214. ->insertAt(1, 'Insert At', ['controller' => 'Insert', 'action' => 'at'])
  215. ->insertAt(1, 'Insert At Again', ['controller' => 'Insert', 'action' => 'at_again']);
  216. $result = $this->breadcrumbs->getCrumbs();
  217. $expected = [
  218. [
  219. 'title' => 'Some text',
  220. 'url' => [
  221. 'controller' => 'Some',
  222. 'action' => 'text',
  223. ],
  224. 'options' => [],
  225. ],
  226. [
  227. 'title' => 'Insert At Again',
  228. 'url' => [
  229. 'controller' => 'Insert',
  230. 'action' => 'at_again',
  231. ],
  232. 'options' => [],
  233. ],
  234. [
  235. 'title' => 'Insert At',
  236. 'url' => [
  237. 'controller' => 'Insert',
  238. 'action' => 'at',
  239. ],
  240. 'options' => [],
  241. ],
  242. [
  243. 'title' => 'Home',
  244. 'url' => '/',
  245. 'options' => [
  246. 'class' => 'first',
  247. ],
  248. ],
  249. ];
  250. $this->assertEquals($expected, $result);
  251. }
  252. /**
  253. * Test adding crumbs to a specific index
  254. *
  255. */
  256. public function testInsertAtIndexOutOfBounds()
  257. {
  258. $this->expectException(\LogicException::class);
  259. $this->breadcrumbs
  260. ->add('Home', '/', ['class' => 'first'])
  261. ->insertAt(2, 'Insert At Again', ['controller' => 'Insert', 'action' => 'at_again']);
  262. }
  263. /**
  264. * Test adding crumbs before a specific one
  265. *
  266. * @return void
  267. */
  268. public function testInsertBefore()
  269. {
  270. $this->breadcrumbs
  271. ->add('Home', '/', ['class' => 'first'])
  272. ->prepend('Some text', ['controller' => 'Some', 'action' => 'text'])
  273. ->prepend('The root', '/root', ['data-name' => 'some-name'])
  274. ->insertBefore('The root', 'The super root');
  275. $result = $this->breadcrumbs->getCrumbs();
  276. $expected = [
  277. [
  278. 'title' => 'The super root',
  279. 'url' => null,
  280. 'options' => [],
  281. ],
  282. [
  283. 'title' => 'The root',
  284. 'url' => '/root',
  285. 'options' => ['data-name' => 'some-name'],
  286. ],
  287. [
  288. 'title' => 'Some text',
  289. 'url' => [
  290. 'controller' => 'Some',
  291. 'action' => 'text',
  292. ],
  293. 'options' => [],
  294. ],
  295. [
  296. 'title' => 'Home',
  297. 'url' => '/',
  298. 'options' => [
  299. 'class' => 'first',
  300. ],
  301. ],
  302. ];
  303. $this->assertEquals($expected, $result);
  304. }
  305. /**
  306. * Test adding crumbs after a specific one
  307. *
  308. * @return void
  309. */
  310. public function testInsertAfter()
  311. {
  312. $this->breadcrumbs
  313. ->add('Home', '/', ['class' => 'first'])
  314. ->prepend('Some text', ['controller' => 'Some', 'action' => 'text'])
  315. ->prepend('The root', '/root', ['data-name' => 'some-name'])
  316. ->insertAfter('The root', 'The less super root');
  317. $result = $this->breadcrumbs->getCrumbs();
  318. $expected = [
  319. [
  320. 'title' => 'The root',
  321. 'url' => '/root',
  322. 'options' => ['data-name' => 'some-name'],
  323. ],
  324. [
  325. 'title' => 'The less super root',
  326. 'url' => null,
  327. 'options' => [],
  328. ],
  329. [
  330. 'title' => 'Some text',
  331. 'url' => [
  332. 'controller' => 'Some',
  333. 'action' => 'text',
  334. ],
  335. 'options' => [],
  336. ],
  337. [
  338. 'title' => 'Home',
  339. 'url' => '/',
  340. 'options' => [
  341. 'class' => 'first',
  342. ],
  343. ],
  344. ];
  345. $this->assertEquals($expected, $result);
  346. }
  347. /**
  348. * Tests the render method
  349. *
  350. * @return void
  351. */
  352. public function testRender()
  353. {
  354. $this->assertSame('', $this->breadcrumbs->render());
  355. $this->breadcrumbs
  356. ->add('Home', '/', ['class' => 'first', 'innerAttrs' => ['data-foo' => 'bar']])
  357. ->add('Some text', ['controller' => 'tests_apps', 'action' => 'some_method'])
  358. ->add('Final crumb', null, ['class' => 'final', 'innerAttrs' => ['class' => 'final-link']]);
  359. $result = $this->breadcrumbs->render(
  360. ['data-stuff' => 'foo and bar'],
  361. ['separator' => '<i class="fa fa-angle-right"></i>', 'class' => 'separator']
  362. );
  363. $expected = [
  364. ['ul' => ['data-stuff' => 'foo and bar']],
  365. ['li' => ['class' => 'first']],
  366. ['a' => ['href' => '/', 'data-foo' => 'bar']],
  367. 'Home',
  368. '/a',
  369. '/li',
  370. ['li' => ['class' => 'separator']],
  371. ['span' => []],
  372. ['i' => ['class' => 'fa fa-angle-right']],
  373. '/i',
  374. '/span',
  375. '/li',
  376. ['li' => []],
  377. ['a' => ['href' => '/some_alias']],
  378. 'Some text',
  379. '/a',
  380. '/li',
  381. ['li' => ['class' => 'separator']],
  382. ['span' => []],
  383. ['i' => ['class' => 'fa fa-angle-right']],
  384. '/i',
  385. '/span',
  386. '/li',
  387. ['li' => ['class' => 'final']],
  388. ['span' => ['class' => 'final-link']],
  389. 'Final crumb',
  390. '/span',
  391. '/li',
  392. '/ul',
  393. ];
  394. $this->assertHtml($expected, $result);
  395. }
  396. /**
  397. * Tests the render method with custom templates
  398. *
  399. * @return void
  400. */
  401. public function testRenderCustomTemplate()
  402. {
  403. $this->breadcrumbs = new BreadcrumbsHelper(new View(), [
  404. 'templates' => [
  405. 'wrapper' => '<ol itemtype="http://schema.org/BreadcrumbList"{{attrs}}>{{content}}</ol>',
  406. 'item' => '<li itemprop="itemListElement" itemtype="http://schema.org/ListItem"{{attrs}}><a itemtype="http://schema.org/Thing" itemprop="item" href="{{url}}"{{innerAttrs}}><span itemprop="name">{{title}}</span></a></li>',
  407. 'itemWithoutLink' => '<li itemprop="itemListElement" itemtype="http://schema.org/ListItem"{{attrs}}><span itemprop="name"{{innerAttrs}}>{{title}}</span></li>',
  408. ],
  409. ]);
  410. $this->breadcrumbs
  411. ->add('Home', '/', ['class' => 'first', 'innerAttrs' => ['data-foo' => 'bar']])
  412. ->add('Final crumb', null, ['class' => 'final', 'innerAttrs' => ['class' => 'final-link']]);
  413. $result = $this->breadcrumbs->render(
  414. ['data-stuff' => 'foo and bar'],
  415. ['separator' => ' > ', 'class' => 'separator']
  416. );
  417. $expected = [
  418. ['ol' => ['itemtype' => 'http://schema.org/BreadcrumbList', 'data-stuff' => 'foo and bar']],
  419. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'first']],
  420. ['a' => ['itemtype' => 'http://schema.org/Thing', 'itemprop' => 'item', 'href' => '/', 'data-foo' => 'bar']],
  421. ['span' => ['itemprop' => 'name']],
  422. 'Home',
  423. '/span',
  424. '/a',
  425. '/li',
  426. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'final']],
  427. ['span' => ['itemprop' => 'name', 'class' => 'final-link']],
  428. 'Final crumb',
  429. '/span',
  430. '/li',
  431. '/ol',
  432. ];
  433. $this->assertHtml($expected, $result, true);
  434. }
  435. /**
  436. * Tests the render method with template vars
  437. *
  438. * @return void
  439. */
  440. public function testRenderCustomTemplateTemplateVars()
  441. {
  442. $this->breadcrumbs = new BreadcrumbsHelper(new View(), [
  443. 'templates' => [
  444. 'wrapper' => '{{thing}}<ol itemtype="http://schema.org/BreadcrumbList"{{attrs}}>{{content}}</ol>',
  445. 'item' => '<li itemprop="itemListElement" itemtype="http://schema.org/ListItem"{{attrs}}><a itemtype="http://schema.org/Thing" itemprop="item" href="{{url}}"{{innerAttrs}}><span itemprop="name">{{title}}</span></a>{{foo}}</li>',
  446. 'itemWithoutLink' => '<li itemprop="itemListElement" itemtype="http://schema.org/ListItem"{{attrs}}><span itemprop="name"{{innerAttrs}}>{{title}}</span>{{barbaz}}</li>',
  447. ],
  448. ]);
  449. $this->breadcrumbs
  450. ->add('Home', '/', ['class' => 'first', 'innerAttrs' => ['data-foo' => 'bar'], 'templateVars' => ['foo' => 'barbaz']])
  451. ->add('Final crumb', null, ['class' => 'final', 'innerAttrs' => ['class' => 'final-link'], 'templateVars' => ['barbaz' => 'foo']]);
  452. $result = $this->breadcrumbs->render(
  453. ['data-stuff' => 'foo and bar', 'templateVars' => ['thing' => 'somestuff']],
  454. ['separator' => ' > ', 'class' => 'separator']
  455. );
  456. $expected = [
  457. 'somestuff',
  458. ['ol' => ['itemtype' => 'http://schema.org/BreadcrumbList', 'data-stuff' => 'foo and bar']],
  459. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'first']],
  460. ['a' => ['itemtype' => 'http://schema.org/Thing', 'itemprop' => 'item', 'href' => '/', 'data-foo' => 'bar']],
  461. ['span' => ['itemprop' => 'name']],
  462. 'Home',
  463. '/span',
  464. '/a',
  465. 'barbaz',
  466. '/li',
  467. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'final']],
  468. ['span' => ['itemprop' => 'name', 'class' => 'final-link']],
  469. 'Final crumb',
  470. '/span',
  471. 'foo',
  472. '/li',
  473. '/ol',
  474. ];
  475. $this->assertHtml($expected, $result, true);
  476. }
  477. }