CRUDControllerTest.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. <?php
  2. /*
  3. * This file is part of the Sonata 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\Controller;
  11. use Symfony\Component\DependencyInjection\ContainerInterface;
  12. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Sonata\AdminBundle\Controller\CRUDController;
  15. use Sonata\AdminBundle\Admin\Pool;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Bridge\Twig\Extension\FormExtension;
  18. use Symfony\Component\HttpFoundation\Session\Session;
  19. use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
  20. use Sonata\AdminBundle\Exception\ModelManagerException;
  21. use Symfony\Component\HttpFoundation\StreamedResponse;
  22. /**
  23. * Test for CRUDController
  24. *
  25. * @author Andrej Hudec <pulzarraider@gmail.com>
  26. */
  27. class CRUDControllerTest extends \PHPUnit_Framework_TestCase
  28. {
  29. /**
  30. * @var CRUDController
  31. */
  32. private $controller;
  33. /**
  34. * @var Request
  35. */
  36. private $request;
  37. /**
  38. * @var Sonata\AdminBundle\Admin\AdminInterface
  39. */
  40. private $admin;
  41. /**
  42. * @var Pool
  43. */
  44. private $pool;
  45. /**
  46. * @var array
  47. */
  48. private $parameters;
  49. /**
  50. *
  51. * @var Session
  52. */
  53. private $session;
  54. /**
  55. * {@inheritDoc}
  56. */
  57. protected function setUp()
  58. {
  59. $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
  60. $this->request = new Request();
  61. $this->pool = new Pool($container, 'title', 'logo.png');
  62. $this->request->attributes->set('_sonata_admin', 'foo.admin');
  63. $this->admin = $this->getMock('Sonata\AdminBundle\Admin\AdminInterface');
  64. $this->parameters = array();
  65. // php 5.3 BC
  66. $params = &$this->parameters;
  67. $templating = $this->getMock('Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine', array(), array($container, array()));
  68. $templating->expects($this->any())
  69. ->method('renderResponse')
  70. ->will($this->returnCallback(function($view, array $parameters = array(), Response $response = null) use (&$params) {
  71. if (null === $response) {
  72. $response = new Response();
  73. }
  74. $params = $parameters;
  75. return $response;
  76. }));
  77. $this->session = new Session(new MockArraySessionStorage());
  78. // php 5.3 BC
  79. $pool = $this->pool;
  80. $request = $this->request;
  81. $admin = $this->admin;
  82. $session = $this->session;
  83. $twig = $this->getMockBuilder('Twig_Environment')
  84. ->disableOriginalConstructor()
  85. ->getMock();
  86. $twigRenderer = $this->getMock('Symfony\Bridge\Twig\Form\TwigRendererInterface');
  87. $formExtension = new FormExtension($twigRenderer);
  88. $twig->expects($this->any())
  89. ->method('getExtension')
  90. ->will($this->returnCallback(function($name) use ($formExtension) {
  91. switch ($name) {
  92. case 'form':
  93. return $formExtension;
  94. }
  95. return null;
  96. }));
  97. $exporter = $this->getMock('Sonata\AdminBundle\Export\Exporter');
  98. $exporter->expects($this->any())
  99. ->method('getResponse')
  100. ->will($this->returnValue(new StreamedResponse()));
  101. $container->expects($this->any())
  102. ->method('get')
  103. ->will($this->returnCallback(function($id) use ($pool, $request, $admin, $templating, $twig, $session, $exporter) {
  104. switch ($id) {
  105. case 'sonata.admin.pool':
  106. return $pool;
  107. case 'request':
  108. return $request;
  109. case 'foo.admin':
  110. return $admin;
  111. case 'templating':
  112. return $templating;
  113. case 'twig':
  114. return $twig;
  115. case 'session':
  116. return $session;
  117. case 'sonata.admin.exporter':
  118. return $exporter;
  119. }
  120. return null;
  121. }));
  122. $this->admin->expects($this->any())
  123. ->method('getTemplate')
  124. ->will($this->returnCallback(function($name) {
  125. switch ($name) {
  126. case 'ajax':
  127. return 'SonataAdminBundle::ajax_layout.html.twig';
  128. case 'layout':
  129. return 'SonataAdminBundle::standard_layout.html.twig';
  130. case 'show':
  131. return 'SonataAdminBundle:CRUD:show.html.twig';
  132. case 'edit':
  133. return 'SonataAdminBundle:CRUD:edit.html.twig';
  134. }
  135. return null;
  136. }));
  137. $this->admin->expects($this->any())
  138. ->method('getIdParameter')
  139. ->will($this->returnValue('id'));
  140. $this->admin->expects($this->any())
  141. ->method('generateUrl')
  142. ->will($this->returnCallback(function($name, array $parameters = array(), $absolute = false) {
  143. $result = $name;
  144. if (!empty($parameters)) {
  145. $result .= '?'.http_build_query($parameters);
  146. }
  147. return $result;
  148. }));
  149. $this->admin->expects($this->any())
  150. ->method('generateObjectUrl')
  151. ->will($this->returnCallback(function($name, $object, array $parameters = array(), $absolute = false) {
  152. $result = get_class($object).'_'.$name;
  153. if (!empty($parameters)) {
  154. $result .= '?'.http_build_query($parameters);
  155. }
  156. return $result;
  157. }));
  158. $this->controller = new CRUDController();
  159. $this->controller->setContainer($container);
  160. }
  161. public function testRenderJson1()
  162. {
  163. $data = array('example'=>'123', 'foo'=>'bar');
  164. $this->request->headers->set('Content-Type', 'application/x-www-form-urlencoded');
  165. $response = $this->controller->renderJson($data);
  166. $this->assertEquals($response->headers->get('Content-Type'), 'application/json');
  167. $this->assertEquals(json_encode($data), $response->getContent());
  168. }
  169. public function testRenderJson2()
  170. {
  171. $data = array('example'=>'123', 'foo'=>'bar');
  172. $this->request->headers->set('Content-Type', 'multipart/form-data');
  173. $response = $this->controller->renderJson($data);
  174. $this->assertEquals($response->headers->get('Content-Type'), 'application/json');
  175. $this->assertEquals(json_encode($data), $response->getContent());
  176. }
  177. public function testRenderJsonAjax()
  178. {
  179. $data = array('example'=>'123', 'foo'=>'bar');
  180. $this->request->attributes->set('_xml_http_request', true);
  181. $this->request->headers->set('Content-Type', 'multipart/form-data');
  182. $response = $this->controller->renderJson($data);
  183. $this->assertEquals($response->headers->get('Content-Type'), 'text/plain');
  184. $this->assertEquals(json_encode($data), $response->getContent());
  185. }
  186. public function testIsXmlHttpRequest()
  187. {
  188. $this->assertFalse($this->controller->isXmlHttpRequest());
  189. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  190. $this->assertTrue($this->controller->isXmlHttpRequest());
  191. $this->request->headers->remove('X-Requested-With');
  192. $this->assertFalse($this->controller->isXmlHttpRequest());
  193. $this->request->attributes->set('_xml_http_request', true);
  194. $this->assertTrue($this->controller->isXmlHttpRequest());
  195. }
  196. public function testConfigureWithException()
  197. {
  198. $this->setExpectedException('RuntimeException', 'There is no `_sonata_admin` defined for the controller `Sonata\AdminBundle\Controller\CRUDController`');
  199. $this->request->attributes->remove('_sonata_admin');
  200. $this->controller->configure();
  201. }
  202. public function testConfigureWithException2()
  203. {
  204. $this->setExpectedException('RuntimeException', 'Unable to find the admin class related to the current controller (Sonata\AdminBundle\Controller\CRUDController)');
  205. $this->request->attributes->set('_sonata_admin', 'nonexistent.admin');
  206. $this->controller->configure();
  207. }
  208. public function testGetBaseTemplate()
  209. {
  210. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->controller->getBaseTemplate());
  211. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  212. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->controller->getBaseTemplate());
  213. $this->request->headers->remove('X-Requested-With');
  214. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->controller->getBaseTemplate());
  215. $this->request->attributes->set('_xml_http_request', true);
  216. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->controller->getBaseTemplate());
  217. }
  218. public function testRender()
  219. {
  220. $this->parameters = array();
  221. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->render('FooAdminBundle::foo.html.twig', array()));
  222. $this->assertEquals($this->admin, $this->parameters['admin']);
  223. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  224. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  225. }
  226. public function testRenderCustomParams()
  227. {
  228. $this->parameters = array();
  229. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->render('FooAdminBundle::foo.html.twig', array('foo'=>'bar')));
  230. $this->assertEquals($this->admin, $this->parameters['admin']);
  231. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  232. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  233. $this->assertEquals('bar', $this->parameters['foo']);
  234. }
  235. public function testRenderAjax()
  236. {
  237. $this->parameters = array();
  238. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  239. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->render('FooAdminBundle::foo.html.twig', array('foo'=>'bar')));
  240. $this->assertEquals($this->admin, $this->parameters['admin']);
  241. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->parameters['base_template']);
  242. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  243. $this->assertEquals('bar', $this->parameters['foo']);
  244. }
  245. public function testListActionAccessDenied()
  246. {
  247. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  248. $this->admin->expects($this->once())
  249. ->method('isGranted')
  250. ->with($this->equalTo('LIST'))
  251. ->will($this->returnValue(false));
  252. $this->controller->listAction();
  253. }
  254. public function testListAction()
  255. {
  256. $datagrid = $this->getMock('Sonata\AdminBundle\Datagrid\DatagridInterface');
  257. $this->admin->expects($this->once())
  258. ->method('isGranted')
  259. ->with($this->equalTo('LIST'))
  260. ->will($this->returnValue(true));
  261. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  262. ->disableOriginalConstructor()
  263. ->getMock();
  264. $form->expects($this->once())
  265. ->method('createView')
  266. ->will($this->returnValue($this->getMock('Symfony\Component\Form\FormView')));
  267. $this->admin->expects($this->once())
  268. ->method('getDatagrid')
  269. ->will($this->returnValue($datagrid));
  270. $datagrid->expects($this->once())
  271. ->method('getForm')
  272. ->will($this->returnValue($form));
  273. $this->parameters = array();
  274. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->listAction());
  275. $this->assertEquals($this->admin, $this->parameters['admin']);
  276. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  277. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  278. $this->assertEquals('list', $this->parameters['action']);
  279. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  280. $this->assertInstanceOf('Sonata\AdminBundle\Datagrid\DatagridInterface', $this->parameters['datagrid']);
  281. $this->assertEquals('', $this->parameters['csrf_token']);
  282. }
  283. public function testBatchActionDeleteAccessDenied()
  284. {
  285. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  286. $this->admin->expects($this->once())
  287. ->method('isGranted')
  288. ->with($this->equalTo('DELETE'))
  289. ->will($this->returnValue(false));
  290. $this->controller->batchActionDelete($this->getMock('Sonata\AdminBundle\Datagrid\ProxyQueryInterface'));
  291. }
  292. public function testBatchActionDelete()
  293. {
  294. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  295. $this->admin->expects($this->once())
  296. ->method('isGranted')
  297. ->with($this->equalTo('DELETE'))
  298. ->will($this->returnValue(true));
  299. $this->admin->expects($this->once())
  300. ->method('getModelManager')
  301. ->will($this->returnValue($modelManager));
  302. $this->admin->expects($this->once())
  303. ->method('getFilterParameters')
  304. ->will($this->returnValue(array('foo'=>'bar')));
  305. $result = $this->controller->batchActionDelete($this->getMock('Sonata\AdminBundle\Datagrid\ProxyQueryInterface'));
  306. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  307. $this->assertSame(array('flash_batch_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  308. $this->assertEquals('list?filter%5Bfoo%5D=bar', $result->getTargetUrl());
  309. }
  310. public function testBatchActionDeleteWithModelManagerException()
  311. {
  312. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  313. $modelManager->expects($this->once())
  314. ->method('batchDelete')
  315. ->will($this->returnCallback(function() {
  316. throw new ModelManagerException();
  317. }));
  318. $this->admin->expects($this->once())
  319. ->method('getModelManager')
  320. ->will($this->returnValue($modelManager));
  321. $this->admin->expects($this->once())
  322. ->method('getFilterParameters')
  323. ->will($this->returnValue(array('foo'=>'bar')));
  324. $result = $this->controller->batchActionDelete($this->getMock('Sonata\AdminBundle\Datagrid\ProxyQueryInterface'));
  325. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  326. $this->assertSame(array('flash_batch_delete_error'), $this->session->getFlashBag()->get('sonata_flash_error'));
  327. $this->assertEquals('list?filter%5Bfoo%5D=bar', $result->getTargetUrl());
  328. }
  329. public function testShowActionNotFoundException()
  330. {
  331. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  332. $this->admin->expects($this->once())
  333. ->method('getObject')
  334. ->will($this->returnValue(false));
  335. $this->controller->showAction();
  336. }
  337. public function testShowActionAccessDenied()
  338. {
  339. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  340. $this->admin->expects($this->once())
  341. ->method('getObject')
  342. ->will($this->returnValue(new \stdClass()));
  343. $this->admin->expects($this->once())
  344. ->method('isGranted')
  345. ->with($this->equalTo('VIEW'))
  346. ->will($this->returnValue(false));
  347. $this->controller->showAction();
  348. }
  349. public function testShowAction()
  350. {
  351. $object = new \stdClass();
  352. $this->admin->expects($this->once())
  353. ->method('getObject')
  354. ->will($this->returnValue($object));
  355. $this->admin->expects($this->once())
  356. ->method('isGranted')
  357. ->with($this->equalTo('VIEW'))
  358. ->will($this->returnValue(true));
  359. $show = $this->getMock('Sonata\AdminBundle\Admin\FieldDescriptionCollection');
  360. $this->admin->expects($this->once())
  361. ->method('getShow')
  362. ->will($this->returnValue($show));
  363. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->showAction());
  364. $this->assertEquals($this->admin, $this->parameters['admin']);
  365. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  366. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  367. $this->assertEquals('show', $this->parameters['action']);
  368. $this->assertInstanceOf('Sonata\AdminBundle\Admin\FieldDescriptionCollection', $this->parameters['elements']);
  369. $this->assertEquals($object, $this->parameters['object']);
  370. }
  371. /**
  372. * @dataProvider getRedirectToTests
  373. */
  374. public function testRedirectTo($expected, $queryParams, $hasActiveSubclass)
  375. {
  376. $this->admin->expects($this->any())
  377. ->method('hasActiveSubclass')
  378. ->will($this->returnValue($hasActiveSubclass));
  379. $object = new \stdClass();
  380. foreach ($queryParams as $key => $value) {
  381. $this->request->query->set($key, $value);
  382. }
  383. $response = $this->controller->redirectTo($object);
  384. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  385. $this->assertEquals($expected, $response->getTargetUrl());
  386. }
  387. public function getRedirectToTests()
  388. {
  389. return array(
  390. array('stdClass_edit', array(), false),
  391. array('list', array('btn_update_and_list'=>true), false),
  392. array('list', array('btn_create_and_list'=>true), false),
  393. array('create', array('btn_create_and_create'=>true), false),
  394. array('create?subclass=foo', array('btn_create_and_create'=>true, 'subclass'=>'foo'), true),
  395. );
  396. }
  397. public function testAddFlash()
  398. {
  399. $this->controller->addFlash('foo', 'bar');
  400. $this->assertSame(array('bar'), $this->session->getFlashBag()->get('foo'));
  401. }
  402. public function testDeleteActionNotFoundException()
  403. {
  404. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  405. $this->admin->expects($this->once())
  406. ->method('getObject')
  407. ->will($this->returnValue(false));
  408. $this->controller->deleteAction(1);
  409. }
  410. public function testDeleteActionAccessDenied()
  411. {
  412. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  413. $this->admin->expects($this->once())
  414. ->method('getObject')
  415. ->will($this->returnValue(new \stdClass()));
  416. $this->admin->expects($this->once())
  417. ->method('isGranted')
  418. ->with($this->equalTo('DELETE'))
  419. ->will($this->returnValue(false));
  420. $this->controller->deleteAction(1);
  421. }
  422. public function testDeleteAction()
  423. {
  424. $object = new \stdClass();
  425. $this->admin->expects($this->once())
  426. ->method('getObject')
  427. ->will($this->returnValue($object));
  428. $this->admin->expects($this->once())
  429. ->method('isGranted')
  430. ->with($this->equalTo('DELETE'))
  431. ->will($this->returnValue(true));
  432. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->deleteAction(1));
  433. $this->assertEquals($this->admin, $this->parameters['admin']);
  434. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  435. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  436. $this->assertEquals('delete', $this->parameters['action']);
  437. $this->assertEquals($object, $this->parameters['object']);
  438. $this->assertEquals('', $this->parameters['csrf_token']);
  439. }
  440. public function testDeleteActionAjaxSuccess()
  441. {
  442. $object = new \stdClass();
  443. $this->admin->expects($this->once())
  444. ->method('getObject')
  445. ->will($this->returnValue($object));
  446. $this->admin->expects($this->once())
  447. ->method('isGranted')
  448. ->with($this->equalTo('DELETE'))
  449. ->will($this->returnValue(true));
  450. $this->request->setMethod('DELETE');
  451. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  452. $response = $this->controller->deleteAction(1);
  453. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  454. $this->assertEquals(json_encode(array('result'=>'ok')), $response->getContent());
  455. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  456. }
  457. public function testDeleteActionAjaxError()
  458. {
  459. $object = new \stdClass();
  460. $this->admin->expects($this->once())
  461. ->method('getObject')
  462. ->will($this->returnValue($object));
  463. $this->admin->expects($this->once())
  464. ->method('isGranted')
  465. ->with($this->equalTo('DELETE'))
  466. ->will($this->returnValue(true));
  467. $this->admin->expects($this->once())
  468. ->method('delete')
  469. ->will($this->returnCallback(function() {
  470. throw new ModelManagerException();
  471. }));
  472. $this->request->setMethod('DELETE');
  473. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  474. $response = $this->controller->deleteAction(1);
  475. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  476. $this->assertEquals(json_encode(array('result'=>'error')), $response->getContent());
  477. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  478. }
  479. public function testDeleteActionSuccess()
  480. {
  481. $object = new \stdClass();
  482. $this->admin->expects($this->once())
  483. ->method('getObject')
  484. ->will($this->returnValue($object));
  485. $this->admin->expects($this->once())
  486. ->method('isGranted')
  487. ->with($this->equalTo('DELETE'))
  488. ->will($this->returnValue(true));
  489. $this->request->setMethod('DELETE');
  490. $response = $this->controller->deleteAction(1);
  491. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  492. $this->assertSame(array('flash_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  493. $this->assertEquals('list', $response->getTargetUrl());
  494. }
  495. public function testDeleteActionError()
  496. {
  497. $object = new \stdClass();
  498. $this->admin->expects($this->once())
  499. ->method('getObject')
  500. ->will($this->returnValue($object));
  501. $this->admin->expects($this->once())
  502. ->method('isGranted')
  503. ->with($this->equalTo('DELETE'))
  504. ->will($this->returnValue(true));
  505. $this->admin->expects($this->once())
  506. ->method('delete')
  507. ->will($this->returnCallback(function() {
  508. throw new ModelManagerException();
  509. }));
  510. $this->request->setMethod('DELETE');
  511. $response = $this->controller->deleteAction(1);
  512. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  513. $this->assertSame(array('flash_delete_error'), $this->session->getFlashBag()->get('sonata_flash_error'));
  514. $this->assertEquals('list', $response->getTargetUrl());
  515. }
  516. public function testEditActionNotFoundException()
  517. {
  518. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  519. $this->admin->expects($this->once())
  520. ->method('getObject')
  521. ->will($this->returnValue(false));
  522. $this->controller->editAction();
  523. }
  524. public function testEditActionAccessDenied()
  525. {
  526. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  527. $this->admin->expects($this->once())
  528. ->method('getObject')
  529. ->will($this->returnValue(new \stdClass()));
  530. $this->admin->expects($this->once())
  531. ->method('isGranted')
  532. ->with($this->equalTo('EDIT'))
  533. ->will($this->returnValue(false));
  534. $this->controller->editAction();
  535. }
  536. public function testEditAction()
  537. {
  538. $object = new \stdClass();
  539. $this->admin->expects($this->once())
  540. ->method('getObject')
  541. ->will($this->returnValue($object));
  542. $this->admin->expects($this->once())
  543. ->method('isGranted')
  544. ->with($this->equalTo('EDIT'))
  545. ->will($this->returnValue(true));
  546. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  547. ->disableOriginalConstructor()
  548. ->getMock();
  549. $this->admin->expects($this->once())
  550. ->method('getForm')
  551. ->will($this->returnValue($form));
  552. $formView = $this->getMock('Symfony\Component\Form\FormView');
  553. $form->expects($this->any())
  554. ->method('createView')
  555. ->will($this->returnValue($formView));
  556. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  557. $this->assertEquals($this->admin, $this->parameters['admin']);
  558. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  559. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  560. $this->assertEquals('edit', $this->parameters['action']);
  561. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  562. $this->assertEquals($object, $this->parameters['object']);
  563. }
  564. public function testEditActionSuccess()
  565. {
  566. $object = new \stdClass();
  567. $this->admin->expects($this->once())
  568. ->method('getObject')
  569. ->will($this->returnValue($object));
  570. $this->admin->expects($this->once())
  571. ->method('isGranted')
  572. ->with($this->equalTo('EDIT'))
  573. ->will($this->returnValue(true));
  574. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  575. ->disableOriginalConstructor()
  576. ->getMock();
  577. $this->admin->expects($this->once())
  578. ->method('getForm')
  579. ->will($this->returnValue($form));
  580. $form->expects($this->once())
  581. ->method('isValid')
  582. ->will($this->returnValue(true));
  583. $this->request->setMethod('POST');
  584. $response = $this->controller->editAction();
  585. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  586. $this->assertSame(array('flash_edit_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  587. $this->assertEquals('stdClass_edit', $response->getTargetUrl());
  588. }
  589. public function testEditActionError()
  590. {
  591. $object = new \stdClass();
  592. $this->admin->expects($this->once())
  593. ->method('getObject')
  594. ->will($this->returnValue($object));
  595. $this->admin->expects($this->once())
  596. ->method('isGranted')
  597. ->with($this->equalTo('EDIT'))
  598. ->will($this->returnValue(true));
  599. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  600. ->disableOriginalConstructor()
  601. ->getMock();
  602. $this->admin->expects($this->once())
  603. ->method('getForm')
  604. ->will($this->returnValue($form));
  605. $form->expects($this->once())
  606. ->method('isValid')
  607. ->will($this->returnValue(false));
  608. $this->request->setMethod('POST');
  609. $formView = $this->getMock('Symfony\Component\Form\FormView');
  610. $form->expects($this->any())
  611. ->method('createView')
  612. ->will($this->returnValue($formView));
  613. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  614. $this->assertEquals($this->admin, $this->parameters['admin']);
  615. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  616. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  617. $this->assertEquals('edit', $this->parameters['action']);
  618. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  619. $this->assertEquals($object, $this->parameters['object']);
  620. }
  621. public function testEditActionAjaxSuccess()
  622. {
  623. $object = new \stdClass();
  624. $this->admin->expects($this->once())
  625. ->method('getObject')
  626. ->will($this->returnValue($object));
  627. $this->admin->expects($this->once())
  628. ->method('isGranted')
  629. ->with($this->equalTo('EDIT'))
  630. ->will($this->returnValue(true));
  631. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  632. ->disableOriginalConstructor()
  633. ->getMock();
  634. $this->admin->expects($this->once())
  635. ->method('getForm')
  636. ->will($this->returnValue($form));
  637. $form->expects($this->once())
  638. ->method('isValid')
  639. ->will($this->returnValue(true));
  640. $this->admin->expects($this->once())
  641. ->method('getNormalizedIdentifier')
  642. ->with($this->equalTo($object))
  643. ->will($this->returnValue('foo_normalized'));
  644. $this->request->setMethod('POST');
  645. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  646. $response = $this->controller->editAction();
  647. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  648. $this->assertEquals(json_encode(array('result'=>'ok', 'objectId' => 'foo_normalized')), $response->getContent());
  649. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  650. }
  651. public function testEditActionAjaxError()
  652. {
  653. $object = new \stdClass();
  654. $this->admin->expects($this->once())
  655. ->method('getObject')
  656. ->will($this->returnValue($object));
  657. $this->admin->expects($this->once())
  658. ->method('isGranted')
  659. ->with($this->equalTo('EDIT'))
  660. ->will($this->returnValue(true));
  661. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  662. ->disableOriginalConstructor()
  663. ->getMock();
  664. $this->admin->expects($this->once())
  665. ->method('getForm')
  666. ->will($this->returnValue($form));
  667. $form->expects($this->once())
  668. ->method('isValid')
  669. ->will($this->returnValue(false));
  670. $this->request->setMethod('POST');
  671. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  672. $formView = $this->getMock('Symfony\Component\Form\FormView');
  673. $form->expects($this->any())
  674. ->method('createView')
  675. ->will($this->returnValue($formView));
  676. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  677. $this->assertEquals($this->admin, $this->parameters['admin']);
  678. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->parameters['base_template']);
  679. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  680. $this->assertEquals('edit', $this->parameters['action']);
  681. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  682. $this->assertEquals($object, $this->parameters['object']);
  683. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  684. }
  685. public function testExportActionAccessDenied()
  686. {
  687. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  688. $this->admin->expects($this->once())
  689. ->method('isGranted')
  690. ->with($this->equalTo('EXPORT'))
  691. ->will($this->returnValue(false));
  692. $this->controller->exportAction($this->request);
  693. }
  694. public function testExportActionWrongFormat()
  695. {
  696. $this->setExpectedException('RuntimeException', 'Export in format `csv` is not allowed for class: `Foo`. Allowed formats are: `json`');
  697. $this->admin->expects($this->once())
  698. ->method('isGranted')
  699. ->with($this->equalTo('EXPORT'))
  700. ->will($this->returnValue(true));
  701. $this->admin->expects($this->once())
  702. ->method('getExportFormats')
  703. ->will($this->returnValue(array('json')));
  704. $this->admin->expects($this->once())
  705. ->method('getClass')
  706. ->will($this->returnValue('Foo'));
  707. $this->request->query->set('format', 'csv');
  708. $this->controller->exportAction($this->request);
  709. }
  710. public function testExportAction()
  711. {
  712. $this->admin->expects($this->once())
  713. ->method('isGranted')
  714. ->with($this->equalTo('EXPORT'))
  715. ->will($this->returnValue(true));
  716. $this->admin->expects($this->once())
  717. ->method('getExportFormats')
  718. ->will($this->returnValue(array('json')));
  719. $dataSourceIterator = $this->getMock('Exporter\Source\SourceIteratorInterface');
  720. $this->admin->expects($this->once())
  721. ->method('getDataSourceIterator')
  722. ->will($this->returnValue($dataSourceIterator));
  723. $this->request->query->set('format', 'json');
  724. $response = $this->controller->exportAction($this->request);
  725. $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response);
  726. $this->assertEquals(200, $response->getStatusCode());
  727. }
  728. }