BreadcrumbsHelperTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  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. public function testInsertAtIndexOutOfBounds()
  256. {
  257. $this->expectException(\LogicException::class);
  258. $this->breadcrumbs
  259. ->add('Home', '/', ['class' => 'first'])
  260. ->insertAt(2, 'Insert At Again', ['controller' => 'Insert', 'action' => 'at_again']);
  261. }
  262. /**
  263. * Test adding crumbs before a specific one
  264. *
  265. * @return void
  266. */
  267. public function testInsertBefore()
  268. {
  269. $this->breadcrumbs
  270. ->add('Home', '/', ['class' => 'first'])
  271. ->prepend('Some text', ['controller' => 'Some', 'action' => 'text'])
  272. ->prepend('The root', '/root', ['data-name' => 'some-name'])
  273. ->insertBefore('The root', 'The super root');
  274. $result = $this->breadcrumbs->getCrumbs();
  275. $expected = [
  276. [
  277. 'title' => 'The super root',
  278. 'url' => null,
  279. 'options' => [],
  280. ],
  281. [
  282. 'title' => 'The root',
  283. 'url' => '/root',
  284. 'options' => ['data-name' => 'some-name'],
  285. ],
  286. [
  287. 'title' => 'Some text',
  288. 'url' => [
  289. 'controller' => 'Some',
  290. 'action' => 'text',
  291. ],
  292. 'options' => [],
  293. ],
  294. [
  295. 'title' => 'Home',
  296. 'url' => '/',
  297. 'options' => [
  298. 'class' => 'first',
  299. ],
  300. ],
  301. ];
  302. $this->assertEquals($expected, $result);
  303. }
  304. /**
  305. * Test adding crumbs after a specific one
  306. *
  307. * @return void
  308. */
  309. public function testInsertAfter()
  310. {
  311. $this->breadcrumbs
  312. ->add('Home', '/', ['class' => 'first'])
  313. ->prepend('Some text', ['controller' => 'Some', 'action' => 'text'])
  314. ->prepend('The root', '/root', ['data-name' => 'some-name'])
  315. ->insertAfter('The root', 'The less super root');
  316. $result = $this->breadcrumbs->getCrumbs();
  317. $expected = [
  318. [
  319. 'title' => 'The root',
  320. 'url' => '/root',
  321. 'options' => ['data-name' => 'some-name'],
  322. ],
  323. [
  324. 'title' => 'The less super root',
  325. 'url' => null,
  326. 'options' => [],
  327. ],
  328. [
  329. 'title' => 'Some text',
  330. 'url' => [
  331. 'controller' => 'Some',
  332. 'action' => 'text',
  333. ],
  334. 'options' => [],
  335. ],
  336. [
  337. 'title' => 'Home',
  338. 'url' => '/',
  339. 'options' => [
  340. 'class' => 'first',
  341. ],
  342. ],
  343. ];
  344. $this->assertEquals($expected, $result);
  345. }
  346. /**
  347. * Test adding crumbs after a specific one
  348. */
  349. public function testInsertAfterLastItem()
  350. {
  351. $this->breadcrumbs
  352. ->add('Home', '/')
  353. ->insertAfter('Home', 'Below Home', '/below', ['class' => 'second']);
  354. $result = $this->breadcrumbs->getCrumbs();
  355. $expected = [
  356. [
  357. 'title' => 'Home',
  358. 'url' => '/',
  359. 'options' => [],
  360. ],
  361. [
  362. 'title' => 'Below Home',
  363. 'url' => '/below',
  364. 'options' => [
  365. 'class' => 'second',
  366. ],
  367. ],
  368. ];
  369. $this->assertEquals($expected, $result);
  370. }
  371. /**
  372. * Tests the render method
  373. *
  374. * @return void
  375. */
  376. public function testRender()
  377. {
  378. $this->assertSame('', $this->breadcrumbs->render());
  379. $this->breadcrumbs
  380. ->add('Home', '/', ['class' => 'first', 'innerAttrs' => ['data-foo' => 'bar']])
  381. ->add('Some text', ['controller' => 'tests_apps', 'action' => 'some_method'])
  382. ->add('Final crumb', null, ['class' => 'final', 'innerAttrs' => ['class' => 'final-link']]);
  383. $result = $this->breadcrumbs->render(
  384. ['data-stuff' => 'foo and bar'],
  385. ['separator' => '<i class="fa fa-angle-right"></i>', 'class' => 'separator']
  386. );
  387. $expected = [
  388. ['ul' => ['data-stuff' => 'foo and bar']],
  389. ['li' => ['class' => 'first']],
  390. ['a' => ['href' => '/', 'data-foo' => 'bar']],
  391. 'Home',
  392. '/a',
  393. '/li',
  394. ['li' => ['class' => 'separator']],
  395. ['span' => []],
  396. ['i' => ['class' => 'fa fa-angle-right']],
  397. '/i',
  398. '/span',
  399. '/li',
  400. ['li' => []],
  401. ['a' => ['href' => '/some_alias']],
  402. 'Some text',
  403. '/a',
  404. '/li',
  405. ['li' => ['class' => 'separator']],
  406. ['span' => []],
  407. ['i' => ['class' => 'fa fa-angle-right']],
  408. '/i',
  409. '/span',
  410. '/li',
  411. ['li' => ['class' => 'final']],
  412. ['span' => ['class' => 'final-link']],
  413. 'Final crumb',
  414. '/span',
  415. '/li',
  416. '/ul',
  417. ];
  418. $this->assertHtml($expected, $result);
  419. }
  420. /**
  421. * Tests the render method with custom templates
  422. *
  423. * @return void
  424. */
  425. public function testRenderCustomTemplate()
  426. {
  427. $this->breadcrumbs = new BreadcrumbsHelper(new View(), [
  428. 'templates' => [
  429. 'wrapper' => '<ol itemtype="http://schema.org/BreadcrumbList"{{attrs}}>{{content}}</ol>',
  430. '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>',
  431. 'itemWithoutLink' => '<li itemprop="itemListElement" itemtype="http://schema.org/ListItem"{{attrs}}><span itemprop="name"{{innerAttrs}}>{{title}}</span></li>',
  432. ],
  433. ]);
  434. $this->breadcrumbs
  435. ->add('Home', '/', ['class' => 'first', 'innerAttrs' => ['data-foo' => 'bar']])
  436. ->add('Final crumb', null, ['class' => 'final', 'innerAttrs' => ['class' => 'final-link']]);
  437. $result = $this->breadcrumbs->render(
  438. ['data-stuff' => 'foo and bar'],
  439. ['separator' => ' > ', 'class' => 'separator']
  440. );
  441. $expected = [
  442. ['ol' => ['itemtype' => 'http://schema.org/BreadcrumbList', 'data-stuff' => 'foo and bar']],
  443. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'first']],
  444. ['a' => ['itemtype' => 'http://schema.org/Thing', 'itemprop' => 'item', 'href' => '/', 'data-foo' => 'bar']],
  445. ['span' => ['itemprop' => 'name']],
  446. 'Home',
  447. '/span',
  448. '/a',
  449. '/li',
  450. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'final']],
  451. ['span' => ['itemprop' => 'name', 'class' => 'final-link']],
  452. 'Final crumb',
  453. '/span',
  454. '/li',
  455. '/ol',
  456. ];
  457. $this->assertHtml($expected, $result, true);
  458. }
  459. /**
  460. * Tests the render method with template vars
  461. *
  462. * @return void
  463. */
  464. public function testRenderCustomTemplateTemplateVars()
  465. {
  466. $this->breadcrumbs = new BreadcrumbsHelper(new View(), [
  467. 'templates' => [
  468. 'wrapper' => '{{thing}}<ol itemtype="http://schema.org/BreadcrumbList"{{attrs}}>{{content}}</ol>',
  469. '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>',
  470. 'itemWithoutLink' => '<li itemprop="itemListElement" itemtype="http://schema.org/ListItem"{{attrs}}><span itemprop="name"{{innerAttrs}}>{{title}}</span>{{barbaz}}</li>',
  471. ],
  472. ]);
  473. $this->breadcrumbs
  474. ->add('Home', '/', ['class' => 'first', 'innerAttrs' => ['data-foo' => 'bar'], 'templateVars' => ['foo' => 'barbaz']])
  475. ->add('Final crumb', null, ['class' => 'final', 'innerAttrs' => ['class' => 'final-link'], 'templateVars' => ['barbaz' => 'foo']]);
  476. $result = $this->breadcrumbs->render(
  477. ['data-stuff' => 'foo and bar', 'templateVars' => ['thing' => 'somestuff']],
  478. ['separator' => ' > ', 'class' => 'separator']
  479. );
  480. $expected = [
  481. 'somestuff',
  482. ['ol' => ['itemtype' => 'http://schema.org/BreadcrumbList', 'data-stuff' => 'foo and bar']],
  483. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'first']],
  484. ['a' => ['itemtype' => 'http://schema.org/Thing', 'itemprop' => 'item', 'href' => '/', 'data-foo' => 'bar']],
  485. ['span' => ['itemprop' => 'name']],
  486. 'Home',
  487. '/span',
  488. '/a',
  489. 'barbaz',
  490. '/li',
  491. ['li' => ['itemprop' => 'itemListElement', 'itemtype' => 'http://schema.org/ListItem', 'class' => 'final']],
  492. ['span' => ['itemprop' => 'name', 'class' => 'final-link']],
  493. 'Final crumb',
  494. '/span',
  495. 'foo',
  496. '/li',
  497. '/ol',
  498. ];
  499. $this->assertHtml($expected, $result, true);
  500. }
  501. }