BreadcrumbsBuilderTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. <?php
  2. /*
  3. * This file is part of the Sonata Project package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Tests\Admin;
  11. use Sonata\AdminBundle\Admin\BreadcrumbsBuilder;
  12. use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentAdmin;
  13. use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
  14. use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment;
  15. use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\DummySubject;
  16. use Symfony\Component\HttpFoundation\Request;
  17. /**
  18. * This test class contains unit and integration tests. Maybe it could be
  19. * separated into two classes.
  20. *
  21. * @author Grégoire Paris <postmaster@greg0ire.fr>
  22. */
  23. class BreadcrumbsBuilderTest extends \PHPUnit_Framework_TestCase
  24. {
  25. /**
  26. * @group legacy
  27. */
  28. public function testGetBreadcrumbs()
  29. {
  30. $class = 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\DummySubject';
  31. $baseControllerName = 'SonataNewsBundle:PostAdmin';
  32. $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
  33. $commentAdmin = new CommentAdmin(
  34. 'sonata.post.admin.comment',
  35. 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment',
  36. 'SonataNewsBundle:CommentAdmin'
  37. );
  38. $subCommentAdmin = new CommentAdmin(
  39. 'sonata.post.admin.comment',
  40. 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment',
  41. 'SonataNewsBundle:CommentAdmin'
  42. );
  43. $admin->addChild($commentAdmin);
  44. $admin->setRequest(new Request(array('id' => 42)));
  45. $commentAdmin->setRequest(new Request());
  46. $commentAdmin->initialize();
  47. $admin->initialize();
  48. $commentAdmin->setCurrentChild($subCommentAdmin);
  49. $menuFactory = $this->getMock('Knp\Menu\FactoryInterface');
  50. $menu = $this->getMock('Knp\Menu\ItemInterface');
  51. $translatorStrategy = $this->getMock(
  52. 'Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface'
  53. );
  54. $routeGenerator = $this->getMock(
  55. 'Sonata\AdminBundle\Route\RouteGeneratorInterface'
  56. );
  57. $modelManager = $this->getMock(
  58. 'Sonata\AdminBundle\Model\ModelManagerInterface'
  59. );
  60. $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
  61. $container->expects($this->any())
  62. ->method('getParameter')
  63. ->with('sonata.admin.configuration.breadcrumbs')
  64. ->will($this->returnValue(array()));
  65. $pool = $this->getMockBuilder('Sonata\AdminBundle\Admin\Pool')
  66. ->disableOriginalConstructor()
  67. ->getMock();
  68. $pool->expects($this->any())
  69. ->method('getContainer')
  70. ->will($this->returnValue($container));
  71. $admin->setConfigurationPool($pool);
  72. $admin->setMenuFactory($menuFactory);
  73. $admin->setLabelTranslatorStrategy($translatorStrategy);
  74. $admin->setRouteGenerator($routeGenerator);
  75. $admin->setModelManager($modelManager);
  76. $commentAdmin->setLabelTranslatorStrategy($translatorStrategy);
  77. $commentAdmin->setRouteGenerator($routeGenerator);
  78. $modelManager->expects($this->exactly(1))
  79. ->method('find')
  80. ->with('Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\DummySubject', 42)
  81. ->will($this->returnValue(new DummySubject()));
  82. $menuFactory->expects($this->exactly(5))
  83. ->method('createItem')
  84. ->with('root')
  85. ->will($this->returnValue($menu));
  86. $menu->expects($this->once())
  87. ->method('setUri')
  88. ->with($this->identicalTo(false));
  89. $menu->expects($this->exactly(5))
  90. ->method('getParent')
  91. ->will($this->returnValue(false));
  92. $routeGenerator->expects($this->exactly(5))
  93. ->method('generate')
  94. ->with('sonata_admin_dashboard')
  95. ->will($this->returnValue('http://somehost.com'));
  96. $translatorStrategy->expects($this->exactly(18))
  97. ->method('getLabel')
  98. ->withConsecutive(
  99. array('dashboard'),
  100. array('DummySubject_list'),
  101. array('Comment_list'),
  102. array('Comment_repost'),
  103. array('dashboard'),
  104. array('DummySubject_list'),
  105. array('Comment_list'),
  106. array('Comment_flag'),
  107. array('dashboard'),
  108. array('DummySubject_list'),
  109. array('Comment_list'),
  110. array('Comment_edit'),
  111. array('dashboard'),
  112. array('DummySubject_list'),
  113. array('Comment_list'),
  114. array('dashboard'),
  115. array('DummySubject_list'),
  116. array('Comment_list')
  117. )
  118. ->will($this->onConsecutiveCalls(
  119. 'someLabel',
  120. 'someOtherLabel',
  121. 'someInterestingLabel',
  122. 'someFancyLabel',
  123. 'someCoolLabel',
  124. 'someTipTopLabel',
  125. 'someFunkyLabel',
  126. 'someAwesomeLabel',
  127. 'someLikeableLabel',
  128. 'someMildlyInterestingLabel',
  129. 'someWTFLabel',
  130. 'someBadLabel',
  131. 'someBoringLabel',
  132. 'someLongLabel',
  133. 'someEndlessLabel',
  134. 'someAlmostThereLabel',
  135. 'someOriginalLabel',
  136. 'someOkayishLabel'
  137. ));
  138. $menu->expects($this->exactly(24))
  139. ->method('addChild')
  140. ->withConsecutive(
  141. array('someLabel'),
  142. array('someOtherLabel'),
  143. array('dummy subject representation'),
  144. array('someInterestingLabel'),
  145. array('someFancyLabel'),
  146. array('someCoolLabel'),
  147. array('someTipTopLabel'),
  148. array('dummy subject representation'),
  149. array('someFunkyLabel'),
  150. array('someAwesomeLabel'),
  151. array('someLikeableLabel'),
  152. array('someMildlyInterestingLabel'),
  153. array('dummy subject representation'),
  154. array('someWTFLabel'),
  155. array('someBadLabel'),
  156. array('someBoringLabel'),
  157. array('someLongLabel'),
  158. array('dummy subject representation'),
  159. array('someEndlessLabel'),
  160. array('someAlmostThereLabel'),
  161. array('someOriginalLabel'),
  162. array('dummy subject representation'),
  163. array('someOkayishLabel'),
  164. array('this is a comment')
  165. )
  166. ->will($this->returnValue($menu));
  167. $admin->getBreadcrumbs('repost');
  168. $admin->setSubject(new DummySubject());
  169. $admin->getBreadcrumbs('flag');
  170. $commentAdmin->setConfigurationPool($pool);
  171. $commentAdmin->getBreadcrumbs('edit');
  172. $commentAdmin->getBreadcrumbs('list');
  173. $commentAdmin->setSubject(new Comment());
  174. $commentAdmin->getBreadcrumbs('reply');
  175. }
  176. /**
  177. * @group legacy
  178. */
  179. public function testGetBreadcrumbsWithNoCurrentAdmin()
  180. {
  181. $class = 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\DummySubject';
  182. $baseControllerName = 'SonataNewsBundle:PostAdmin';
  183. $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
  184. $commentAdmin = new CommentAdmin(
  185. 'sonata.post.admin.comment',
  186. 'Application\Sonata\NewsBundle\Entity\Comment',
  187. 'SonataNewsBundle:CommentAdmin'
  188. );
  189. $admin->addChild($commentAdmin);
  190. $admin->setRequest(new Request(array('id' => 42)));
  191. $commentAdmin->setRequest(new Request());
  192. $commentAdmin->initialize();
  193. $admin->initialize();
  194. $menuFactory = $this->getMock('Knp\Menu\FactoryInterface');
  195. $menu = $this->getMock('Knp\Menu\ItemInterface');
  196. $translatorStrategy = $this->getMock(
  197. 'Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface'
  198. );
  199. $routeGenerator = $this->getMock(
  200. 'Sonata\AdminBundle\Route\RouteGeneratorInterface'
  201. );
  202. $admin->setMenuFactory($menuFactory);
  203. $admin->setLabelTranslatorStrategy($translatorStrategy);
  204. $admin->setRouteGenerator($routeGenerator);
  205. $menuFactory->expects($this->any())
  206. ->method('createItem')
  207. ->with('root')
  208. ->will($this->returnValue($menu));
  209. $translatorStrategy->expects($this->any())
  210. ->method('getLabel')
  211. ->withConsecutive(
  212. array('dashboard'),
  213. array('DummySubject_list'),
  214. array('DummySubject_repost'),
  215. array('dashboard'),
  216. array('DummySubject_list')
  217. )
  218. ->will($this->onConsecutiveCalls(
  219. 'someLabel',
  220. 'someOtherLabel',
  221. 'someInterestingLabel',
  222. 'someFancyLabel',
  223. 'someCoolLabel'
  224. ));
  225. $menu->expects($this->any())
  226. ->method('addChild')
  227. ->withConsecutive(
  228. array('someLabel'),
  229. array('someOtherLabel'),
  230. array('someInterestingLabel'),
  231. array('someFancyLabel'),
  232. array('someCoolLabel'),
  233. array('dummy subject representation')
  234. )
  235. ->will($this->returnValue($menu));
  236. $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
  237. $container->expects($this->any())
  238. ->method('getParameter')
  239. ->with('sonata.admin.configuration.breadcrumbs')
  240. ->will($this->returnValue(array()));
  241. $pool = $this->getMockBuilder('Sonata\AdminBundle\Admin\Pool')
  242. ->disableOriginalConstructor()
  243. ->getMock();
  244. $pool->expects($this->any())
  245. ->method('getContainer')
  246. ->will($this->returnValue($container));
  247. $admin->setConfigurationPool($pool);
  248. $admin->getBreadcrumbs('repost');
  249. $admin->setSubject(new DummySubject());
  250. $flagBreadcrumb = $admin->getBreadcrumbs('flag');
  251. $this->assertSame($flagBreadcrumb, $admin->getBreadcrumbs('flag'));
  252. }
  253. public function testUnitChildGetBreadCrumbs()
  254. {
  255. $menu = $this->prophesize('Knp\Menu\ItemInterface');
  256. $menu->getParent()->willReturn(null);
  257. $dashboardMenu = $this->prophesize('Knp\Menu\ItemInterface');
  258. $dashboardMenu->getParent()->willReturn($menu);
  259. $adminListMenu = $this->prophesize('Knp\Menu\ItemInterface');
  260. $adminListMenu->getParent()->willReturn($dashboardMenu);
  261. $adminSubjectMenu = $this->prophesize('Knp\Menu\ItemInterface');
  262. $adminSubjectMenu->getParent()->willReturn($adminListMenu);
  263. $childMenu = $this->prophesize('Knp\Menu\ItemInterface');
  264. $childMenu->getParent()->willReturn($adminSubjectMenu);
  265. $leafMenu = $this->prophesize('Knp\Menu\ItemInterface');
  266. $leafMenu->getParent()->willReturn($childMenu);
  267. $action = 'my_action';
  268. $breadcrumbsBuilder = new BreadcrumbsBuilder(array('child_admin_route' => 'show'));
  269. $admin = $this->prophesize('Sonata\AdminBundle\Admin\AbstractAdmin');
  270. $admin->isChild()->willReturn(false);
  271. $menuFactory = $this->prophesize('Knp\Menu\MenuFactory');
  272. $menuFactory->createItem('root')->willReturn($menu);
  273. $admin->getMenuFactory()->willReturn($menuFactory);
  274. $labelTranslatorStrategy = $this->prophesize(
  275. 'Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface'
  276. );
  277. $labelTranslatorStrategy->getLabel(
  278. 'dashboard',
  279. 'breadcrumb',
  280. 'link'
  281. )->willReturn('Dashboard');
  282. $routeGenerator = $this->prophesize('Sonata\AdminBundle\Route\RouteGeneratorInterface');
  283. $routeGenerator->generate('sonata_admin_dashboard')->willReturn('/dashboard');
  284. $admin->getRouteGenerator()->willReturn($routeGenerator->reveal());
  285. $menu->addChild('Dashboard', array(
  286. 'uri' => '/dashboard',
  287. 'extras' => array(
  288. 'translation_domain' => 'SonataAdminBundle',
  289. ),
  290. ))->willReturn(
  291. $dashboardMenu->reveal()
  292. );
  293. $labelTranslatorStrategy->getLabel(
  294. 'my_class_name_list',
  295. 'breadcrumb',
  296. 'link'
  297. )->willReturn('My class');
  298. $labelTranslatorStrategy->getLabel(
  299. 'my_child_class_name_list',
  300. 'breadcrumb',
  301. 'link'
  302. )->willReturn('My child class');
  303. $childAdmin = $this->prophesize('Sonata\AdminBundle\Admin\AbstractAdmin');
  304. $childAdmin->isChild()->willReturn(true);
  305. $childAdmin->getParent()->willReturn($admin->reveal());
  306. $childAdmin->getTranslationDomain()->willReturn('ChildBundle');
  307. $childAdmin->getLabelTranslatorStrategy()
  308. ->shouldBeCalled()
  309. ->willReturn($labelTranslatorStrategy->reveal());
  310. $childAdmin->getClassnameLabel()->willReturn('my_child_class_name');
  311. $childAdmin->hasRoute('list')->willReturn(true);
  312. $childAdmin->isGranted('LIST')->willReturn(true);
  313. $childAdmin->generateUrl('list')->willReturn('/myadmin/my-object/mychildadmin/list');
  314. $childAdmin->getCurrentChildAdmin()->willReturn(null);
  315. $childAdmin->hasSubject()->willReturn(true);
  316. $childAdmin->getSubject()->willReturn('my subject');
  317. $childAdmin->toString('my subject')->willReturn('My subject');
  318. $admin->hasAccess('show', 'my subject')->willReturn(true)->shouldBeCalled();
  319. $admin->hasRoute('show')->willReturn(true);
  320. $admin->generateUrl('show', array('id' => 'my-object'))->willReturn('/myadmin/my-object');
  321. $admin->trans('My class', array(), null)->willReturn('Ma classe');
  322. $admin->hasRoute('list')->willReturn(true);
  323. $admin->isGranted('LIST')->willReturn(true);
  324. $admin->generateUrl('list')->willReturn('/myadmin/list');
  325. $admin->getCurrentChildAdmin()->willReturn($childAdmin->reveal());
  326. $request = $this->prophesize('Symfony\Component\HttpFoundation\Request');
  327. $request->get('slug')->willReturn('my-object');
  328. $admin->getIdParameter()->willReturn('slug');
  329. $admin->hasRoute('edit')->willReturn(true);
  330. $admin->isGranted('EDIT')->willReturn(true);
  331. $admin->generateUrl('edit', array('id' => 'my-object'))->willReturn('/myadmin/my-object');
  332. $admin->getRequest()->willReturn($request->reveal());
  333. $admin->hasSubject()->willReturn(true);
  334. $admin->getSubject()->willReturn('my subject');
  335. $admin->toString('my subject')->willReturn('My subject');
  336. $admin->getTranslationDomain()->willReturn('FooBundle');
  337. $admin->getLabelTranslatorStrategy()->willReturn(
  338. $labelTranslatorStrategy->reveal()
  339. );
  340. $admin->getClassnameLabel()->willReturn('my_class_name');
  341. $dashboardMenu->addChild('My class', array(
  342. 'extras' => array(
  343. 'translation_domain' => 'FooBundle',
  344. ),
  345. 'uri' => '/myadmin/list',
  346. ))->shouldBeCalled()->willReturn($adminListMenu->reveal());
  347. $adminListMenu->addChild('My subject', array(
  348. 'uri' => '/myadmin/my-object',
  349. 'extras' => array(
  350. 'translation_domain' => false,
  351. ),
  352. ))->shouldBeCalled()->willReturn($adminSubjectMenu->reveal());
  353. $adminSubjectMenu->addChild('My child class', array(
  354. 'extras' => array(
  355. 'translation_domain' => 'ChildBundle',
  356. ),
  357. 'uri' => '/myadmin/my-object/mychildadmin/list',
  358. ))->shouldBeCalled()->willReturn($childMenu->reveal());
  359. $adminSubjectMenu->setExtra('safe_label', false)->willReturn($childMenu);
  360. $childMenu->addChild('My subject', array(
  361. 'extras' => array(
  362. 'translation_domain' => false,
  363. ),
  364. ))->shouldBeCalled()->willReturn($leafMenu->reveal());
  365. $breadcrumbs = $breadcrumbsBuilder->getBreadcrumbs($childAdmin->reveal(), $action);
  366. $this->assertCount(5, $breadcrumbs);
  367. }
  368. public function actionProvider()
  369. {
  370. return array(
  371. array('my_action'),
  372. array('list'),
  373. array('edit'),
  374. array('create'),
  375. );
  376. }
  377. /**
  378. * @dataProvider actionProvider
  379. */
  380. public function testUnitBuildBreadcrumbs($action)
  381. {
  382. $breadcrumbsBuilder = new BreadcrumbsBuilder();
  383. $menu = $this->prophesize('Knp\Menu\ItemInterface');
  384. $menuFactory = $this->prophesize('Knp\Menu\MenuFactory');
  385. $menuFactory->createItem('root')->willReturn($menu);
  386. $admin = $this->prophesize('Sonata\AdminBundle\Admin\AbstractAdmin');
  387. $admin->getMenuFactory()->willReturn($menuFactory);
  388. $labelTranslatorStrategy = $this->prophesize(
  389. 'Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface'
  390. );
  391. $labelTranslatorStrategy->getLabel(
  392. 'dashboard',
  393. 'breadcrumb',
  394. 'link'
  395. )->willReturn('Dashboard');
  396. $routeGenerator = $this->prophesize('Sonata\AdminBundle\Route\RouteGeneratorInterface');
  397. $routeGenerator->generate('sonata_admin_dashboard')->willReturn('/dashboard');
  398. $admin->getRouteGenerator()->willReturn($routeGenerator->reveal());
  399. $menu->addChild('Dashboard', array(
  400. 'uri' => '/dashboard',
  401. 'extras' => array(
  402. 'translation_domain' => 'SonataAdminBundle',
  403. ),
  404. ))->willReturn(
  405. $menu->reveal()
  406. );
  407. $labelTranslatorStrategy->getLabel(
  408. 'my_class_name_list',
  409. 'breadcrumb',
  410. 'link'
  411. )->willReturn('My class');
  412. $labelTranslatorStrategy->getLabel(
  413. 'my_child_class_name_list',
  414. 'breadcrumb',
  415. 'link'
  416. )->willReturn('My child class');
  417. $labelTranslatorStrategy->getLabel(
  418. 'my_child_class_name_my_action',
  419. 'breadcrumb',
  420. 'link'
  421. )->willReturn('My action');
  422. if ($action == 'create') {
  423. $labelTranslatorStrategy->getLabel(
  424. 'my_class_name_create',
  425. 'breadcrumb',
  426. 'link'
  427. )->willReturn('create my object');
  428. $menu->addChild('create my object', array(
  429. 'extras' => array(
  430. 'translation_domain' => 'FooBundle',
  431. ),
  432. ))->willReturn($menu);
  433. }
  434. $childAdmin = $this->prophesize('Sonata\AdminBundle\Admin\AbstractAdmin');
  435. $childAdmin->getTranslationDomain()->willReturn('ChildBundle');
  436. $childAdmin->getLabelTranslatorStrategy()->willReturn($labelTranslatorStrategy->reveal());
  437. $childAdmin->getClassnameLabel()->willReturn('my_child_class_name');
  438. $childAdmin->hasRoute('list')->willReturn(false);
  439. $childAdmin->getCurrentChildAdmin()->willReturn(null);
  440. $childAdmin->hasSubject()->willReturn(false);
  441. $admin->hasRoute('list')->willReturn(true);
  442. $admin->isGranted('LIST')->willReturn(true);
  443. $admin->generateUrl('list')->willReturn('/myadmin/list');
  444. $admin->getCurrentChildAdmin()->willReturn(
  445. $action == 'my_action' ? $childAdmin->reveal() : false
  446. );
  447. if ($action == 'list') {
  448. $admin->isChild()->willReturn(true);
  449. $menu->setUri(false)->shouldBeCalled();
  450. }
  451. $request = $this->prophesize('Symfony\Component\HttpFoundation\Request');
  452. $request->get('slug')->willReturn('my-object');
  453. $admin->getIdParameter()->willReturn('slug');
  454. $admin->hasRoute('edit')->willReturn(false);
  455. $admin->getRequest()->willReturn($request->reveal());
  456. $admin->hasSubject()->willReturn(true);
  457. $admin->getSubject()->willReturn('my subject');
  458. $admin->toString('my subject')->willReturn('My subject');
  459. $admin->getTranslationDomain()->willReturn('FooBundle');
  460. $admin->getLabelTranslatorStrategy()->willReturn(
  461. $labelTranslatorStrategy->reveal()
  462. );
  463. $admin->getClassnameLabel()->willReturn('my_class_name');
  464. $menu->addChild('My class', array(
  465. 'uri' => '/myadmin/list',
  466. 'extras' => array(
  467. 'translation_domain' => 'FooBundle',
  468. ),
  469. ))->willReturn($menu->reveal());
  470. $menu->addChild('My subject', array(
  471. 'extras' => array(
  472. 'translation_domain' => false,
  473. ),
  474. ))->willReturn($menu);
  475. $menu->addChild('My subject', array(
  476. 'uri' => null,
  477. 'extras' => array(
  478. 'translation_domain' => false,
  479. ),
  480. ))->willReturn($menu);
  481. $menu->addChild('My child class', array(
  482. 'extras' => array(
  483. 'translation_domain' => 'ChildBundle',
  484. ),
  485. 'uri' => null,
  486. ))->willReturn($menu);
  487. $menu->setExtra('safe_label', false)->willReturn($menu);
  488. $menu->addChild('My action', array(
  489. 'extras' => array(
  490. 'translation_domain' => 'ChildBundle',
  491. ),
  492. ))->willReturn($menu);
  493. $breadcrumbsBuilder->buildBreadCrumbs($admin->reveal(), $action);
  494. }
  495. }