BreadcrumbsBuilderTest.php 21 KB

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