CRUDControllerTest.php 107 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929
  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. use Sonata\AdminBundle\Util\AdminObjectAclManipulator;
  23. use Sonata\AdminBundle\Admin\FieldDescriptionCollection;
  24. use Sonata\AdminBundle\Tests\Fixtures\Controller\BatchAdminController;
  25. use Symfony\Component\HttpKernel\Kernel;
  26. use Symfony\Component\HttpKernel\Exception\HttpException;
  27. use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
  28. use Sonata\AdminBundle\Admin\AdminInterface;
  29. /**
  30. * Test for CRUDController
  31. *
  32. * @author Andrej Hudec <pulzarraider@gmail.com>
  33. */
  34. class CRUDControllerTest extends \PHPUnit_Framework_TestCase
  35. {
  36. /**
  37. * @var CRUDController
  38. */
  39. private $controller;
  40. /**
  41. * @var Request
  42. */
  43. private $request;
  44. /**
  45. * @var AdminInterface
  46. */
  47. private $admin;
  48. /**
  49. * @var Pool
  50. */
  51. private $pool;
  52. /**
  53. * @var array
  54. */
  55. private $parameters;
  56. /**
  57. * @var Session
  58. */
  59. private $session;
  60. /**
  61. * @var Sonata\AdminBundle\Model\AuditManager
  62. */
  63. private $auditManager;
  64. /**
  65. * @var ContainerInterface
  66. */
  67. private $container;
  68. /**
  69. * @var AdminObjectAclManipulator
  70. */
  71. private $adminObjectAclManipulator;
  72. /**
  73. * @var string
  74. */
  75. private $template;
  76. /**
  77. * @var array
  78. */
  79. private $protectedTestedMethods;
  80. /**
  81. * @var CsrfProviderInterface
  82. */
  83. private $csrfProvider;
  84. /**
  85. * {@inheritDoc}
  86. */
  87. protected function setUp()
  88. {
  89. $this->container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
  90. $this->request = new Request();
  91. $this->pool = new Pool($this->container, 'title', 'logo.png');
  92. $this->pool->setAdminServiceIds(array('foo.admin'));
  93. $this->request->attributes->set('_sonata_admin', 'foo.admin');
  94. $this->admin = $this->getMock('Sonata\AdminBundle\Admin\AdminInterface');
  95. $this->parameters = array();
  96. $this->template = '';
  97. // php 5.3 BC
  98. $params = &$this->parameters;
  99. $template = &$this->template;
  100. $templating = $this->getMock(
  101. 'Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine',
  102. array(),
  103. array($this->container, array())
  104. );
  105. $templating->expects($this->any())
  106. ->method('renderResponse')
  107. ->will($this->returnCallback(function (
  108. $view,
  109. array $parameters = array(),
  110. Response $response = null
  111. ) use (
  112. &$params,
  113. &$template
  114. ) {
  115. $template = $view;
  116. if (null === $response) {
  117. $response = new Response();
  118. }
  119. $params = $parameters;
  120. return $response;
  121. }));
  122. $this->session = new Session(new MockArraySessionStorage());
  123. // php 5.3 BC
  124. $pool = $this->pool;
  125. $request = $this->request;
  126. $admin = $this->admin;
  127. $session = $this->session;
  128. $twig = $this->getMockBuilder('Twig_Environment')
  129. ->disableOriginalConstructor()
  130. ->getMock();
  131. $twigRenderer = $this->getMock('Symfony\Bridge\Twig\Form\TwigRendererInterface');
  132. $formExtension = new FormExtension($twigRenderer);
  133. $twig->expects($this->any())
  134. ->method('getExtension')
  135. ->will($this->returnCallback(function ($name) use ($formExtension) {
  136. switch ($name) {
  137. case 'form':
  138. return $formExtension;
  139. }
  140. return null;
  141. }));
  142. $exporter = $this->getMock('Sonata\AdminBundle\Export\Exporter');
  143. $exporter->expects($this->any())
  144. ->method('getResponse')
  145. ->will($this->returnValue(new StreamedResponse()));
  146. $this->auditManager = $this->getMockBuilder('Sonata\AdminBundle\Model\AuditManager')
  147. ->disableOriginalConstructor()
  148. ->getMock();
  149. $this->adminObjectAclManipulator = $this->getMockBuilder('Sonata\AdminBundle\Util\AdminObjectAclManipulator')
  150. ->disableOriginalConstructor()
  151. ->getMock();
  152. // php 5.3 BC
  153. $auditManager = $this->auditManager;
  154. $adminObjectAclManipulator = $this->adminObjectAclManipulator;
  155. $this->csrfProvider = $this->getMockBuilder(
  156. 'Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'
  157. )
  158. ->getMock();
  159. $this->csrfProvider->expects($this->any())
  160. ->method('generateCsrfToken')
  161. ->will($this->returnCallback(function ($intention) {
  162. return 'csrf-token-123_'.$intention;
  163. }));
  164. $this->csrfProvider->expects($this->any())
  165. ->method('isCsrfTokenValid')
  166. ->will($this->returnCallback(function ($intention, $token) {
  167. if ($token == 'csrf-token-123_'.$intention) {
  168. return true;
  169. }
  170. return false;
  171. }));
  172. // php 5.3 BC
  173. $csrfProvider = $this->csrfProvider;
  174. $this->logger = $this->getMock('Psr\Log\LoggerInterface');
  175. $logger = $this->logger; // php 5.3 BC
  176. $requestStack = null;
  177. if (Kernel::MINOR_VERSION > 3) {
  178. $requestStack = new \Symfony\Component\HttpFoundation\RequestStack();
  179. $requestStack->push($request);
  180. }
  181. $this->container->expects($this->any())
  182. ->method('get')
  183. ->will($this->returnCallback(function ($id) use (
  184. $pool,
  185. $request,
  186. $admin,
  187. $templating,
  188. $twig,
  189. $session,
  190. $exporter,
  191. $auditManager,
  192. $adminObjectAclManipulator,
  193. $requestStack,
  194. $csrfProvider,
  195. $logger
  196. ) {
  197. switch ($id) {
  198. case 'sonata.admin.pool':
  199. return $pool;
  200. case 'request_stack':
  201. return $requestStack;
  202. case 'request':
  203. return $request;
  204. case 'foo.admin':
  205. return $admin;
  206. case 'templating':
  207. return $templating;
  208. case 'twig':
  209. return $twig;
  210. case 'session':
  211. return $session;
  212. case 'sonata.admin.exporter':
  213. return $exporter;
  214. case 'sonata.admin.audit.manager':
  215. return $auditManager;
  216. case 'sonata.admin.object.manipulator.acl.admin':
  217. return $adminObjectAclManipulator;
  218. case 'form.csrf_provider':
  219. return $csrfProvider;
  220. case 'logger':
  221. return $logger;
  222. }
  223. return null;
  224. }));
  225. // php 5.3
  226. $tthis = $this;
  227. $this->container->expects($this->any())
  228. ->method('has')
  229. ->will($this->returnCallback(function ($id) use ($tthis) {
  230. if ($id == 'form.csrf_provider' && $tthis->getCsrfProvider()!==null) {
  231. return true;
  232. }
  233. if ($id == 'logger') {
  234. return true;
  235. }
  236. return false;
  237. }));
  238. $this->admin->expects($this->any())
  239. ->method('getTemplate')
  240. ->will($this->returnCallback(function ($name) {
  241. switch ($name) {
  242. case 'ajax':
  243. return 'SonataAdminBundle::ajax_layout.html.twig';
  244. case 'layout':
  245. return 'SonataAdminBundle::standard_layout.html.twig';
  246. case 'show':
  247. return 'SonataAdminBundle:CRUD:show.html.twig';
  248. case 'show_compare':
  249. return 'SonataAdminBundle:CRUD:show_compare.html.twig';
  250. case 'edit':
  251. return 'SonataAdminBundle:CRUD:edit.html.twig';
  252. case 'dashboard':
  253. return 'SonataAdminBundle:Core:dashboard.html.twig';
  254. case 'search':
  255. return 'SonataAdminBundle:Core:search.html.twig';
  256. case 'list':
  257. return 'SonataAdminBundle:CRUD:list.html.twig';
  258. case 'preview':
  259. return 'SonataAdminBundle:CRUD:preview.html.twig';
  260. case 'history':
  261. return 'SonataAdminBundle:CRUD:history.html.twig';
  262. case 'acl':
  263. return 'SonataAdminBundle:CRUD:acl.html.twig';
  264. case 'delete':
  265. return 'SonataAdminBundle:CRUD:delete.html.twig';
  266. case 'batch':
  267. return 'SonataAdminBundle:CRUD:list__batch.html.twig';
  268. case 'batch_confirmation':
  269. return 'SonataAdminBundle:CRUD:batch_confirmation.html.twig';
  270. }
  271. return null;
  272. }));
  273. $this->admin->expects($this->any())
  274. ->method('getIdParameter')
  275. ->will($this->returnValue('id'));
  276. $this->admin->expects($this->any())
  277. ->method('generateUrl')
  278. ->will(
  279. $this->returnCallback(
  280. function ($name, array $parameters = array(), $absolute = false) {
  281. $result = $name;
  282. if (!empty($parameters)) {
  283. $result .= '?'.http_build_query($parameters);
  284. }
  285. return $result;
  286. }
  287. )
  288. );
  289. $this->admin->expects($this->any())
  290. ->method('generateObjectUrl')
  291. ->will(
  292. $this->returnCallback(
  293. function ($name, $object, array $parameters = array(), $absolute = false) {
  294. $result = get_class($object).'_'.$name;
  295. if (!empty($parameters)) {
  296. $result .= '?'.http_build_query($parameters);
  297. }
  298. return $result;
  299. }
  300. )
  301. );
  302. $this->controller = new CRUDController();
  303. $this->controller->setContainer($this->container);
  304. // Make some methods public to test them
  305. $testedMethods = array(
  306. 'renderJson',
  307. 'isXmlHttpRequest',
  308. 'configure',
  309. 'getBaseTemplate',
  310. 'redirectTo',
  311. 'addFlash'
  312. );
  313. foreach ($testedMethods as $testedMethod) {
  314. $method = new \ReflectionMethod('Sonata\\AdminBundle\\Controller\\CRUDController', $testedMethod);
  315. $method->setAccessible(true);
  316. $this->protectedTestedMethods[$testedMethod] = $method;
  317. }
  318. }
  319. public function testRenderJson1()
  320. {
  321. $data = array('example'=>'123', 'foo'=>'bar');
  322. $this->request->headers->set('Content-Type', 'application/x-www-form-urlencoded');
  323. $response = $this->protectedTestedMethods['renderJson']->invoke($this->controller, $data);
  324. $this->assertEquals($response->headers->get('Content-Type'), 'application/json');
  325. $this->assertEquals(json_encode($data), $response->getContent());
  326. }
  327. public function testRenderJson2()
  328. {
  329. $data = array('example'=>'123', 'foo'=>'bar');
  330. $this->request->headers->set('Content-Type', 'multipart/form-data');
  331. $response = $this->protectedTestedMethods['renderJson']->invoke($this->controller, $data);
  332. $this->assertEquals($response->headers->get('Content-Type'), 'application/json');
  333. $this->assertEquals(json_encode($data), $response->getContent());
  334. }
  335. public function testRenderJsonAjax()
  336. {
  337. $data = array('example'=>'123', 'foo'=>'bar');
  338. $this->request->attributes->set('_xml_http_request', true);
  339. $this->request->headers->set('Content-Type', 'multipart/form-data');
  340. $response = $this->protectedTestedMethods['renderJson']->invoke($this->controller, $data);
  341. $this->assertEquals($response->headers->get('Content-Type'), 'text/plain');
  342. $this->assertEquals(json_encode($data), $response->getContent());
  343. }
  344. public function testIsXmlHttpRequest()
  345. {
  346. $this->assertFalse($this->protectedTestedMethods['isXmlHttpRequest']->invoke($this->controller));
  347. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  348. $this->assertTrue($this->protectedTestedMethods['isXmlHttpRequest']->invoke($this->controller));
  349. $this->request->headers->remove('X-Requested-With');
  350. $this->assertFalse($this->protectedTestedMethods['isXmlHttpRequest']->invoke($this->controller));
  351. $this->request->attributes->set('_xml_http_request', true);
  352. $this->assertTrue($this->protectedTestedMethods['isXmlHttpRequest']->invoke($this->controller));
  353. }
  354. public function testConfigure()
  355. {
  356. $uniqueId = '';
  357. $this->admin->expects($this->once())
  358. ->method('setUniqid')
  359. ->will($this->returnCallback(function ($uniqid) use (&$uniqueId) {
  360. $uniqueId = $uniqid;
  361. }));
  362. $this->request->query->set('uniqid', 123456);
  363. $this->protectedTestedMethods['configure']->invoke($this->controller);
  364. $this->assertEquals(123456, $uniqueId);
  365. $this->assertAttributeEquals($this->admin, 'admin', $this->controller);
  366. }
  367. public function testConfigureChild()
  368. {
  369. $uniqueId = '';
  370. $this->admin->expects($this->once())
  371. ->method('setUniqid')
  372. ->will($this->returnCallback(function ($uniqid) use (&$uniqueId) {
  373. $uniqueId = $uniqid;
  374. }));
  375. $this->admin->expects($this->once())
  376. ->method('isChild')
  377. ->will($this->returnValue(true));
  378. $adminParent = $this->getMock('Sonata\AdminBundle\Admin\AdminInterface');
  379. $this->admin->expects($this->once())
  380. ->method('getParent')
  381. ->will($this->returnValue($adminParent));
  382. $this->request->query->set('uniqid', 123456);
  383. $this->protectedTestedMethods['configure']->invoke($this->controller);
  384. $this->assertEquals(123456, $uniqueId);
  385. $this->assertAttributeEquals($adminParent, 'admin', $this->controller);
  386. }
  387. public function testConfigureWithException()
  388. {
  389. $this->setExpectedException(
  390. 'RuntimeException',
  391. 'There is no `_sonata_admin` defined for the controller `Sonata\AdminBundle\Controller\CRUDController`'
  392. );
  393. $this->request->attributes->remove('_sonata_admin');
  394. $this->protectedTestedMethods['configure']->invoke($this->controller);
  395. }
  396. public function testConfigureWithException2()
  397. {
  398. $this->setExpectedException(
  399. 'RuntimeException',
  400. 'Unable to find the admin class related to the current controller ' .
  401. '(Sonata\AdminBundle\Controller\CRUDController)'
  402. );
  403. $this->pool->setAdminServiceIds(array('nonexistent.admin'));
  404. $this->request->attributes->set('_sonata_admin', 'nonexistent.admin');
  405. $this->protectedTestedMethods['configure']->invoke($this->controller);
  406. }
  407. public function testGetBaseTemplate()
  408. {
  409. $this->assertEquals(
  410. 'SonataAdminBundle::standard_layout.html.twig',
  411. $this->protectedTestedMethods['getBaseTemplate']->invoke($this->controller)
  412. );
  413. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  414. $this->assertEquals(
  415. 'SonataAdminBundle::ajax_layout.html.twig',
  416. $this->protectedTestedMethods['getBaseTemplate']->invoke($this->controller)
  417. );
  418. $this->request->headers->remove('X-Requested-With');
  419. $this->assertEquals(
  420. 'SonataAdminBundle::standard_layout.html.twig',
  421. $this->protectedTestedMethods['getBaseTemplate']->invoke($this->controller)
  422. );
  423. $this->request->attributes->set('_xml_http_request', true);
  424. $this->assertEquals(
  425. 'SonataAdminBundle::ajax_layout.html.twig',
  426. $this->protectedTestedMethods['getBaseTemplate']->invoke($this->controller)
  427. );
  428. }
  429. public function testRender()
  430. {
  431. $this->parameters = array();
  432. $this->assertInstanceOf(
  433. 'Symfony\Component\HttpFoundation\Response',
  434. $this->controller->render('FooAdminBundle::foo.html.twig', array())
  435. );
  436. $this->assertEquals($this->admin, $this->parameters['admin']);
  437. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  438. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  439. $this->assertEquals('FooAdminBundle::foo.html.twig', $this->template);
  440. }
  441. public function testRenderWithResponse()
  442. {
  443. $this->parameters = array();
  444. $response = $response = new Response();
  445. $response->headers->set('X-foo', 'bar');
  446. $responseResult = $this->controller->render('FooAdminBundle::foo.html.twig', array(), $response);
  447. $this->assertEquals($response, $responseResult);
  448. $this->assertEquals('bar', $responseResult->headers->get('X-foo'));
  449. $this->assertEquals($this->admin, $this->parameters['admin']);
  450. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  451. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  452. $this->assertEquals('FooAdminBundle::foo.html.twig', $this->template);
  453. }
  454. public function testRenderCustomParams()
  455. {
  456. $this->parameters = array();
  457. $this->assertInstanceOf(
  458. 'Symfony\Component\HttpFoundation\Response',
  459. $this->controller->render('FooAdminBundle::foo.html.twig',
  460. array('foo'=>'bar'))
  461. );
  462. $this->assertEquals($this->admin, $this->parameters['admin']);
  463. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  464. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  465. $this->assertEquals('bar', $this->parameters['foo']);
  466. $this->assertEquals('FooAdminBundle::foo.html.twig', $this->template);
  467. }
  468. public function testRenderAjax()
  469. {
  470. $this->parameters = array();
  471. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  472. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->render('FooAdminBundle::foo.html.twig', array('foo'=>'bar')));
  473. $this->assertEquals($this->admin, $this->parameters['admin']);
  474. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->parameters['base_template']);
  475. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  476. $this->assertEquals('bar', $this->parameters['foo']);
  477. $this->assertEquals('FooAdminBundle::foo.html.twig', $this->template);
  478. }
  479. public function testListActionAccessDenied()
  480. {
  481. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  482. $this->admin->expects($this->once())
  483. ->method('isGranted')
  484. ->with($this->equalTo('LIST'))
  485. ->will($this->returnValue(false));
  486. $this->controller->listAction();
  487. }
  488. public function testListAction()
  489. {
  490. $datagrid = $this->getMock('Sonata\AdminBundle\Datagrid\DatagridInterface');
  491. $this->admin->expects($this->once())
  492. ->method('isGranted')
  493. ->with($this->equalTo('LIST'))
  494. ->will($this->returnValue(true));
  495. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  496. ->disableOriginalConstructor()
  497. ->getMock();
  498. $form->expects($this->once())
  499. ->method('createView')
  500. ->will($this->returnValue($this->getMock('Symfony\Component\Form\FormView')));
  501. $this->admin->expects($this->once())
  502. ->method('getDatagrid')
  503. ->will($this->returnValue($datagrid));
  504. $datagrid->expects($this->once())
  505. ->method('getForm')
  506. ->will($this->returnValue($form));
  507. $this->parameters = array();
  508. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->listAction());
  509. $this->assertEquals($this->admin, $this->parameters['admin']);
  510. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  511. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  512. $this->assertEquals('list', $this->parameters['action']);
  513. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  514. $this->assertInstanceOf('Sonata\AdminBundle\Datagrid\DatagridInterface', $this->parameters['datagrid']);
  515. $this->assertEquals('csrf-token-123_sonata.batch', $this->parameters['csrf_token']);
  516. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  517. $this->assertEquals('SonataAdminBundle:CRUD:list.html.twig', $this->template);
  518. }
  519. public function testBatchActionDeleteAccessDenied()
  520. {
  521. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  522. $this->admin->expects($this->once())
  523. ->method('isGranted')
  524. ->with($this->equalTo('DELETE'))
  525. ->will($this->returnValue(false));
  526. $this->controller->batchActionDelete($this->getMock('Sonata\AdminBundle\Datagrid\ProxyQueryInterface'));
  527. }
  528. public function testBatchActionDelete()
  529. {
  530. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  531. $this->admin->expects($this->once())
  532. ->method('isGranted')
  533. ->with($this->equalTo('DELETE'))
  534. ->will($this->returnValue(true));
  535. $this->admin->expects($this->once())
  536. ->method('getModelManager')
  537. ->will($this->returnValue($modelManager));
  538. $this->admin->expects($this->once())
  539. ->method('getFilterParameters')
  540. ->will($this->returnValue(array('foo'=>'bar')));
  541. $result = $this->controller->batchActionDelete($this->getMock('Sonata\AdminBundle\Datagrid\ProxyQueryInterface'));
  542. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  543. $this->assertSame(array('flash_batch_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  544. $this->assertEquals('list?filter%5Bfoo%5D=bar', $result->getTargetUrl());
  545. }
  546. public function testBatchActionDeleteWithModelManagerException()
  547. {
  548. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  549. $message = 'test message';
  550. $modelManager->expects($this->once())
  551. ->method('batchDelete')
  552. ->will($this->returnCallback(function () use ($message) {
  553. throw new ModelManagerException($message);
  554. }));
  555. $this->logger->expects($this->once())
  556. ->method('error')
  557. ->with($message);
  558. $this->admin->expects($this->once())
  559. ->method('getModelManager')
  560. ->will($this->returnValue($modelManager));
  561. $this->admin->expects($this->once())
  562. ->method('getFilterParameters')
  563. ->will($this->returnValue(array('foo'=>'bar')));
  564. $result = $this->controller->batchActionDelete($this->getMock('Sonata\AdminBundle\Datagrid\ProxyQueryInterface'));
  565. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  566. $this->assertSame(array('flash_batch_delete_error'), $this->session->getFlashBag()->get('sonata_flash_error'));
  567. $this->assertEquals('list?filter%5Bfoo%5D=bar', $result->getTargetUrl());
  568. }
  569. public function testShowActionNotFoundException()
  570. {
  571. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  572. $this->admin->expects($this->once())
  573. ->method('getObject')
  574. ->will($this->returnValue(false));
  575. $this->controller->showAction();
  576. }
  577. public function testShowActionAccessDenied()
  578. {
  579. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  580. $this->admin->expects($this->once())
  581. ->method('getObject')
  582. ->will($this->returnValue(new \stdClass()));
  583. $this->admin->expects($this->once())
  584. ->method('isGranted')
  585. ->with($this->equalTo('VIEW'))
  586. ->will($this->returnValue(false));
  587. $this->controller->showAction();
  588. }
  589. public function testShowAction()
  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('VIEW'))
  598. ->will($this->returnValue(true));
  599. $show = $this->getMock('Sonata\AdminBundle\Admin\FieldDescriptionCollection');
  600. $this->admin->expects($this->once())
  601. ->method('getShow')
  602. ->will($this->returnValue($show));
  603. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->showAction());
  604. $this->assertEquals($this->admin, $this->parameters['admin']);
  605. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  606. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  607. $this->assertEquals('show', $this->parameters['action']);
  608. $this->assertInstanceOf('Sonata\AdminBundle\Admin\FieldDescriptionCollection', $this->parameters['elements']);
  609. $this->assertEquals($object, $this->parameters['object']);
  610. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  611. $this->assertEquals('SonataAdminBundle:CRUD:show.html.twig', $this->template);
  612. }
  613. /**
  614. * @dataProvider getRedirectToTests
  615. */
  616. public function testRedirectTo($expected, $queryParams, $hasActiveSubclass)
  617. {
  618. $this->admin->expects($this->any())
  619. ->method('hasActiveSubclass')
  620. ->will($this->returnValue($hasActiveSubclass));
  621. $object = new \stdClass();
  622. foreach ($queryParams as $key => $value) {
  623. $this->request->query->set($key, $value);
  624. }
  625. $response = $this->protectedTestedMethods['redirectTo']->invoke($this->controller, $object);
  626. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  627. $this->assertEquals($expected, $response->getTargetUrl());
  628. }
  629. public function getRedirectToTests()
  630. {
  631. return array(
  632. array('stdClass_edit', array(), false),
  633. array('list', array('btn_update_and_list'=>true), false),
  634. array('list', array('btn_create_and_list'=>true), false),
  635. array('create', array('btn_create_and_create'=>true), false),
  636. array('create?subclass=foo', array('btn_create_and_create'=>true, 'subclass'=>'foo'), true),
  637. );
  638. }
  639. public function testAddFlash()
  640. {
  641. $this->protectedTestedMethods['addFlash']->invoke($this->controller, 'foo', 'bar');
  642. $this->assertSame(array('bar'), $this->session->getFlashBag()->get('foo'));
  643. }
  644. public function testDeleteActionNotFoundException()
  645. {
  646. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  647. $this->admin->expects($this->once())
  648. ->method('getObject')
  649. ->will($this->returnValue(false));
  650. $this->controller->deleteAction(1);
  651. }
  652. public function testDeleteActionAccessDenied()
  653. {
  654. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  655. $this->admin->expects($this->once())
  656. ->method('getObject')
  657. ->will($this->returnValue(new \stdClass()));
  658. $this->admin->expects($this->once())
  659. ->method('isGranted')
  660. ->with($this->equalTo('DELETE'))
  661. ->will($this->returnValue(false));
  662. $this->controller->deleteAction(1);
  663. }
  664. public function testDeleteAction()
  665. {
  666. $object = new \stdClass();
  667. $this->admin->expects($this->once())
  668. ->method('getObject')
  669. ->will($this->returnValue($object));
  670. $this->admin->expects($this->once())
  671. ->method('isGranted')
  672. ->with($this->equalTo('DELETE'))
  673. ->will($this->returnValue(true));
  674. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->deleteAction(1));
  675. $this->assertEquals($this->admin, $this->parameters['admin']);
  676. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  677. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  678. $this->assertEquals('delete', $this->parameters['action']);
  679. $this->assertEquals($object, $this->parameters['object']);
  680. $this->assertEquals('csrf-token-123_sonata.delete', $this->parameters['csrf_token']);
  681. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  682. $this->assertEquals('SonataAdminBundle:CRUD:delete.html.twig', $this->template);
  683. }
  684. public function testDeleteActionNoCsrfToken()
  685. {
  686. $this->csrfProvider = null;
  687. $object = new \stdClass();
  688. $this->admin->expects($this->once())
  689. ->method('getObject')
  690. ->will($this->returnValue($object));
  691. $this->admin->expects($this->once())
  692. ->method('isGranted')
  693. ->with($this->equalTo('DELETE'))
  694. ->will($this->returnValue(true));
  695. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->deleteAction(1));
  696. $this->assertEquals($this->admin, $this->parameters['admin']);
  697. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  698. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  699. $this->assertEquals('delete', $this->parameters['action']);
  700. $this->assertEquals($object, $this->parameters['object']);
  701. $this->assertEquals('', $this->parameters['csrf_token']);
  702. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  703. $this->assertEquals('SonataAdminBundle:CRUD:delete.html.twig', $this->template);
  704. }
  705. public function testDeleteActionAjaxSuccess1()
  706. {
  707. $object = new \stdClass();
  708. $this->admin->expects($this->once())
  709. ->method('getObject')
  710. ->will($this->returnValue($object));
  711. $this->admin->expects($this->once())
  712. ->method('isGranted')
  713. ->with($this->equalTo('DELETE'))
  714. ->will($this->returnValue(true));
  715. $this->request->setMethod('DELETE');
  716. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  717. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.delete');
  718. $response = $this->controller->deleteAction(1);
  719. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  720. $this->assertEquals(json_encode(array('result'=>'ok')), $response->getContent());
  721. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  722. }
  723. public function testDeleteActionAjaxSuccess2()
  724. {
  725. $object = new \stdClass();
  726. $this->admin->expects($this->once())
  727. ->method('getObject')
  728. ->will($this->returnValue($object));
  729. $this->admin->expects($this->once())
  730. ->method('isGranted')
  731. ->with($this->equalTo('DELETE'))
  732. ->will($this->returnValue(true));
  733. $this->request->setMethod('POST');
  734. $this->request->request->set('_method', 'DELETE');
  735. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.delete');
  736. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  737. $response = $this->controller->deleteAction(1);
  738. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  739. $this->assertEquals(json_encode(array('result'=>'ok')), $response->getContent());
  740. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  741. }
  742. public function testDeleteActionAjaxError()
  743. {
  744. $object = new \stdClass();
  745. $this->admin->expects($this->once())
  746. ->method('getObject')
  747. ->will($this->returnValue($object));
  748. $this->admin->expects($this->once())
  749. ->method('isGranted')
  750. ->with($this->equalTo('DELETE'))
  751. ->will($this->returnValue(true));
  752. $message = 'test message';
  753. $this->admin->expects($this->once())
  754. ->method('delete')
  755. ->will($this->returnCallback(function () use ($message) {
  756. throw new ModelManagerException($message);
  757. }));
  758. $this->logger->expects($this->once())
  759. ->method('error')
  760. ->with($message);
  761. $this->request->setMethod('DELETE');
  762. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.delete');
  763. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  764. $response = $this->controller->deleteAction(1);
  765. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  766. $this->assertEquals(json_encode(array('result'=>'error')), $response->getContent());
  767. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  768. }
  769. public function testDeleteActionSuccess1()
  770. {
  771. $object = new \stdClass();
  772. $this->admin->expects($this->once())
  773. ->method('getObject')
  774. ->will($this->returnValue($object));
  775. $this->admin->expects($this->once())
  776. ->method('toString')
  777. ->with($this->equalTo($object))
  778. ->will($this->returnValue('test'));
  779. $this->expectTranslate('flash_delete_success', array('%name%' => 'test'));
  780. $this->admin->expects($this->once())
  781. ->method('isGranted')
  782. ->with($this->equalTo('DELETE'))
  783. ->will($this->returnValue(true));
  784. $this->request->setMethod('DELETE');
  785. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.delete');
  786. $response = $this->controller->deleteAction(1);
  787. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  788. $this->assertSame(array('flash_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  789. $this->assertEquals('list', $response->getTargetUrl());
  790. }
  791. public function testDeleteActionSuccess2()
  792. {
  793. $object = new \stdClass();
  794. $this->admin->expects($this->once())
  795. ->method('getObject')
  796. ->will($this->returnValue($object));
  797. $this->admin->expects($this->once())
  798. ->method('isGranted')
  799. ->with($this->equalTo('DELETE'))
  800. ->will($this->returnValue(true));
  801. $this->expectTranslate('flash_delete_success');
  802. $this->request->setMethod('POST');
  803. $this->request->request->set('_method', 'DELETE');
  804. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.delete');
  805. $response = $this->controller->deleteAction(1);
  806. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  807. $this->assertSame(array('flash_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  808. $this->assertEquals('list', $response->getTargetUrl());
  809. }
  810. public function testDeleteActionSuccessNoCsrfTokenProvider()
  811. {
  812. $this->csrfProvider = null;
  813. $object = new \stdClass();
  814. $this->admin->expects($this->once())
  815. ->method('getObject')
  816. ->will($this->returnValue($object));
  817. $this->admin->expects($this->once())
  818. ->method('isGranted')
  819. ->with($this->equalTo('DELETE'))
  820. ->will($this->returnValue(true));
  821. $this->expectTranslate('flash_delete_success');
  822. $this->request->setMethod('POST');
  823. $this->request->request->set('_method', 'DELETE');
  824. $response = $this->controller->deleteAction(1);
  825. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  826. $this->assertSame(array('flash_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  827. $this->assertEquals('list', $response->getTargetUrl());
  828. }
  829. public function testDeleteActionWrongRequestMethod()
  830. {
  831. $object = new \stdClass();
  832. $this->admin->expects($this->once())
  833. ->method('getObject')
  834. ->will($this->returnValue($object));
  835. $this->admin->expects($this->once())
  836. ->method('isGranted')
  837. ->with($this->equalTo('DELETE'))
  838. ->will($this->returnValue(true));
  839. //without POST request parameter "_method" should not be used as real REST method
  840. $this->request->query->set('_method', 'DELETE');
  841. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->deleteAction(1));
  842. $this->assertEquals($this->admin, $this->parameters['admin']);
  843. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  844. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  845. $this->assertEquals('delete', $this->parameters['action']);
  846. $this->assertEquals($object, $this->parameters['object']);
  847. $this->assertEquals('csrf-token-123_sonata.delete', $this->parameters['csrf_token']);
  848. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  849. $this->assertEquals('SonataAdminBundle:CRUD:delete.html.twig', $this->template);
  850. }
  851. public function testDeleteActionError()
  852. {
  853. $object = new \stdClass();
  854. $this->admin->expects($this->once())
  855. ->method('getObject')
  856. ->will($this->returnValue($object));
  857. $this->admin->expects($this->once())
  858. ->method('isGranted')
  859. ->with($this->equalTo('DELETE'))
  860. ->will($this->returnValue(true));
  861. $this->expectTranslate('flash_delete_error');
  862. $message = 'test message';
  863. $this->admin->expects($this->once())
  864. ->method('delete')
  865. ->will($this->returnCallback(function () use ($message){
  866. throw new ModelManagerException($message);
  867. }));
  868. $this->logger->expects($this->once())
  869. ->method('error')
  870. ->with($message);
  871. $this->request->setMethod('DELETE');
  872. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.delete');
  873. $response = $this->controller->deleteAction(1);
  874. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  875. $this->assertSame(array('flash_delete_error'), $this->session->getFlashBag()->get('sonata_flash_error'));
  876. $this->assertEquals('list', $response->getTargetUrl());
  877. }
  878. public function testDeleteActionInvalidCsrfToken()
  879. {
  880. $object = new \stdClass();
  881. $this->admin->expects($this->once())
  882. ->method('getObject')
  883. ->will($this->returnValue($object));
  884. $this->admin->expects($this->once())
  885. ->method('isGranted')
  886. ->with($this->equalTo('DELETE'))
  887. ->will($this->returnValue(true));
  888. $this->request->setMethod('POST');
  889. $this->request->request->set('_method', 'DELETE');
  890. $this->request->request->set('_sonata_csrf_token', 'CSRF-INVALID');
  891. try {
  892. $this->controller->deleteAction(1);
  893. } catch (HttpException $e) {
  894. $this->assertEquals('The csrf token is not valid, CSRF attack?', $e->getMessage());
  895. $this->assertEquals(400, $e->getStatusCode());
  896. }
  897. }
  898. public function testEditActionNotFoundException()
  899. {
  900. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  901. $this->admin->expects($this->once())
  902. ->method('getObject')
  903. ->will($this->returnValue(false));
  904. $this->controller->editAction();
  905. }
  906. public function testEditActionAccessDenied()
  907. {
  908. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  909. $this->admin->expects($this->once())
  910. ->method('getObject')
  911. ->will($this->returnValue(new \stdClass()));
  912. $this->admin->expects($this->once())
  913. ->method('isGranted')
  914. ->with($this->equalTo('EDIT'))
  915. ->will($this->returnValue(false));
  916. $this->controller->editAction();
  917. }
  918. public function testEditAction()
  919. {
  920. $object = new \stdClass();
  921. $this->admin->expects($this->once())
  922. ->method('getObject')
  923. ->will($this->returnValue($object));
  924. $this->admin->expects($this->once())
  925. ->method('isGranted')
  926. ->with($this->equalTo('EDIT'))
  927. ->will($this->returnValue(true));
  928. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  929. ->disableOriginalConstructor()
  930. ->getMock();
  931. $this->admin->expects($this->once())
  932. ->method('getForm')
  933. ->will($this->returnValue($form));
  934. $formView = $this->getMock('Symfony\Component\Form\FormView');
  935. $form->expects($this->any())
  936. ->method('createView')
  937. ->will($this->returnValue($formView));
  938. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  939. $this->assertEquals($this->admin, $this->parameters['admin']);
  940. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  941. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  942. $this->assertEquals('edit', $this->parameters['action']);
  943. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  944. $this->assertEquals($object, $this->parameters['object']);
  945. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  946. $this->assertEquals('SonataAdminBundle:CRUD:edit.html.twig', $this->template);
  947. }
  948. public function testEditActionSuccess()
  949. {
  950. $object = new \stdClass();
  951. $this->admin->expects($this->once())
  952. ->method('getObject')
  953. ->will($this->returnValue($object));
  954. $this->admin->expects($this->once())
  955. ->method('update')
  956. ->will($this->returnArgument(0));
  957. $this->admin->expects($this->once())
  958. ->method('isGranted')
  959. ->with($this->equalTo('EDIT'))
  960. ->will($this->returnValue(true));
  961. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  962. ->disableOriginalConstructor()
  963. ->getMock();
  964. $this->admin->expects($this->once())
  965. ->method('getForm')
  966. ->will($this->returnValue($form));
  967. $form->expects($this->once())
  968. ->method('isValid')
  969. ->will($this->returnValue(true));
  970. $this->expectTranslate('flash_edit_success');
  971. $this->request->setMethod('POST');
  972. $response = $this->controller->editAction();
  973. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  974. $this->assertSame(array('flash_edit_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  975. $this->assertEquals('stdClass_edit', $response->getTargetUrl());
  976. }
  977. public function testEditActionError()
  978. {
  979. $object = new \stdClass();
  980. $this->admin->expects($this->once())
  981. ->method('getObject')
  982. ->will($this->returnValue($object));
  983. $this->admin->expects($this->once())
  984. ->method('isGranted')
  985. ->with($this->equalTo('EDIT'))
  986. ->will($this->returnValue(true));
  987. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  988. ->disableOriginalConstructor()
  989. ->getMock();
  990. $this->admin->expects($this->once())
  991. ->method('getForm')
  992. ->will($this->returnValue($form));
  993. $form->expects($this->once())
  994. ->method('isValid')
  995. ->will($this->returnValue(false));
  996. $this->expectTranslate('flash_edit_error');
  997. $this->request->setMethod('POST');
  998. $formView = $this->getMock('Symfony\Component\Form\FormView');
  999. $form->expects($this->any())
  1000. ->method('createView')
  1001. ->will($this->returnValue($formView));
  1002. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  1003. $this->assertEquals($this->admin, $this->parameters['admin']);
  1004. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1005. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1006. $this->assertEquals('edit', $this->parameters['action']);
  1007. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1008. $this->assertEquals($object, $this->parameters['object']);
  1009. $this->assertEquals(array('sonata_flash_error'=>array('flash_edit_error')), $this->session->getFlashBag()->all());
  1010. $this->assertEquals('SonataAdminBundle:CRUD:edit.html.twig', $this->template);
  1011. }
  1012. public function testEditActionAjaxSuccess()
  1013. {
  1014. $object = new \stdClass();
  1015. $this->admin->expects($this->once())
  1016. ->method('getObject')
  1017. ->will($this->returnValue($object));
  1018. $this->admin->expects($this->once())
  1019. ->method('update')
  1020. ->will($this->returnArgument(0));
  1021. $this->admin->expects($this->once())
  1022. ->method('isGranted')
  1023. ->with($this->equalTo('EDIT'))
  1024. ->will($this->returnValue(true));
  1025. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1026. ->disableOriginalConstructor()
  1027. ->getMock();
  1028. $this->admin->expects($this->once())
  1029. ->method('getForm')
  1030. ->will($this->returnValue($form));
  1031. $form->expects($this->once())
  1032. ->method('isValid')
  1033. ->will($this->returnValue(true));
  1034. $this->admin->expects($this->once())
  1035. ->method('getNormalizedIdentifier')
  1036. ->with($this->equalTo($object))
  1037. ->will($this->returnValue('foo_normalized'));
  1038. $this->request->setMethod('POST');
  1039. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  1040. $response = $this->controller->editAction();
  1041. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  1042. $this->assertEquals(json_encode(array('result'=>'ok', 'objectId' => 'foo_normalized')), $response->getContent());
  1043. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1044. }
  1045. public function testEditActionAjaxError()
  1046. {
  1047. $object = new \stdClass();
  1048. $this->admin->expects($this->once())
  1049. ->method('getObject')
  1050. ->will($this->returnValue($object));
  1051. $this->admin->expects($this->once())
  1052. ->method('isGranted')
  1053. ->with($this->equalTo('EDIT'))
  1054. ->will($this->returnValue(true));
  1055. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1056. ->disableOriginalConstructor()
  1057. ->getMock();
  1058. $this->admin->expects($this->once())
  1059. ->method('getForm')
  1060. ->will($this->returnValue($form));
  1061. $form->expects($this->once())
  1062. ->method('isValid')
  1063. ->will($this->returnValue(false));
  1064. $this->request->setMethod('POST');
  1065. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  1066. $formView = $this->getMock('Symfony\Component\Form\FormView');
  1067. $form->expects($this->any())
  1068. ->method('createView')
  1069. ->will($this->returnValue($formView));
  1070. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  1071. $this->assertEquals($this->admin, $this->parameters['admin']);
  1072. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->parameters['base_template']);
  1073. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1074. $this->assertEquals('edit', $this->parameters['action']);
  1075. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1076. $this->assertEquals($object, $this->parameters['object']);
  1077. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1078. $this->assertEquals('SonataAdminBundle:CRUD:edit.html.twig', $this->template);
  1079. }
  1080. public function testEditActionWithPreview()
  1081. {
  1082. $object = new \stdClass();
  1083. $this->admin->expects($this->once())
  1084. ->method('getObject')
  1085. ->will($this->returnValue($object));
  1086. $this->admin->expects($this->once())
  1087. ->method('isGranted')
  1088. ->with($this->equalTo('EDIT'))
  1089. ->will($this->returnValue(true));
  1090. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1091. ->disableOriginalConstructor()
  1092. ->getMock();
  1093. $this->admin->expects($this->once())
  1094. ->method('getForm')
  1095. ->will($this->returnValue($form));
  1096. $this->admin->expects($this->once())
  1097. ->method('supportsPreviewMode')
  1098. ->will($this->returnValue(true));
  1099. $formView = $this->getMock('Symfony\Component\Form\FormView');
  1100. $form->expects($this->any())
  1101. ->method('createView')
  1102. ->will($this->returnValue($formView));
  1103. $form->expects($this->once())
  1104. ->method('isValid')
  1105. ->will($this->returnValue(true));
  1106. $this->request->setMethod('POST');
  1107. $this->request->request->set('btn_preview', 'Preview');
  1108. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->editAction());
  1109. $this->assertEquals($this->admin, $this->parameters['admin']);
  1110. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1111. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1112. $this->assertEquals('edit', $this->parameters['action']);
  1113. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1114. $this->assertEquals($object, $this->parameters['object']);
  1115. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1116. $this->assertEquals('SonataAdminBundle:CRUD:preview.html.twig', $this->template);
  1117. }
  1118. public function testCreateActionAccessDenied()
  1119. {
  1120. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1121. $this->admin->expects($this->once())
  1122. ->method('isGranted')
  1123. ->with($this->equalTo('CREATE'))
  1124. ->will($this->returnValue(false));
  1125. $this->controller->createAction();
  1126. }
  1127. public function testCreateAction()
  1128. {
  1129. $this->admin->expects($this->once())
  1130. ->method('isGranted')
  1131. ->with($this->equalTo('CREATE'))
  1132. ->will($this->returnValue(true));
  1133. $object = new \stdClass();
  1134. $this->admin->expects($this->once())
  1135. ->method('getNewInstance')
  1136. ->will($this->returnValue($object));
  1137. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1138. ->disableOriginalConstructor()
  1139. ->getMock();
  1140. $this->admin->expects($this->once())
  1141. ->method('getForm')
  1142. ->will($this->returnValue($form));
  1143. $formView = $this->getMock('Symfony\Component\Form\FormView');
  1144. $form->expects($this->any())
  1145. ->method('createView')
  1146. ->will($this->returnValue($formView));
  1147. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->createAction());
  1148. $this->assertEquals($this->admin, $this->parameters['admin']);
  1149. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1150. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1151. $this->assertEquals('create', $this->parameters['action']);
  1152. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1153. $this->assertEquals($object, $this->parameters['object']);
  1154. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1155. $this->assertEquals('SonataAdminBundle:CRUD:edit.html.twig', $this->template);
  1156. }
  1157. public function testCreateActionSuccess()
  1158. {
  1159. $object = new \stdClass();
  1160. $this->admin->expects($this->exactly(2))
  1161. ->method('isGranted')
  1162. ->will($this->returnCallback(function ($name, $objectIn = null) use ($object) {
  1163. if ($name != 'CREATE') {
  1164. return false;
  1165. }
  1166. if ($objectIn === null) {
  1167. return true;
  1168. }
  1169. return ($objectIn === $object);
  1170. }));
  1171. $this->admin->expects($this->once())
  1172. ->method('getNewInstance')
  1173. ->will($this->returnValue($object));
  1174. $this->admin->expects($this->once())
  1175. ->method('create')
  1176. ->will($this->returnArgument(0));
  1177. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1178. ->disableOriginalConstructor()
  1179. ->getMock();
  1180. $this->admin->expects($this->once())
  1181. ->method('getForm')
  1182. ->will($this->returnValue($form));
  1183. $form->expects($this->once())
  1184. ->method('isValid')
  1185. ->will($this->returnValue(true));
  1186. $this->expectTranslate('flash_create_success');
  1187. $this->request->setMethod('POST');
  1188. $response = $this->controller->createAction();
  1189. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  1190. $this->assertSame(array('flash_create_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  1191. $this->assertEquals('stdClass_edit', $response->getTargetUrl());
  1192. }
  1193. public function testCreateActionAccessDenied2()
  1194. {
  1195. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1196. $object = new \stdClass();
  1197. $this->admin->expects($this->any())
  1198. ->method('isGranted')
  1199. ->will($this->returnCallback(function ($name, $object = null) {
  1200. if ($name != 'CREATE') {
  1201. return false;
  1202. }
  1203. if ($object === null) {
  1204. return true;
  1205. }
  1206. return false;
  1207. }));
  1208. $this->admin->expects($this->once())
  1209. ->method('getNewInstance')
  1210. ->will($this->returnValue($object));
  1211. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1212. ->disableOriginalConstructor()
  1213. ->getMock();
  1214. $this->admin->expects($this->once())
  1215. ->method('getForm')
  1216. ->will($this->returnValue($form));
  1217. $form->expects($this->once())
  1218. ->method('isValid')
  1219. ->will($this->returnValue(true));
  1220. $this->request->setMethod('POST');
  1221. $this->controller->createAction();
  1222. }
  1223. public function testCreateActionError()
  1224. {
  1225. $this->admin->expects($this->once())
  1226. ->method('isGranted')
  1227. ->with($this->equalTo('CREATE'))
  1228. ->will($this->returnValue(true));
  1229. $object = new \stdClass();
  1230. $this->admin->expects($this->once())
  1231. ->method('getNewInstance')
  1232. ->will($this->returnValue($object));
  1233. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1234. ->disableOriginalConstructor()
  1235. ->getMock();
  1236. $this->admin->expects($this->once())
  1237. ->method('getForm')
  1238. ->will($this->returnValue($form));
  1239. $form->expects($this->once())
  1240. ->method('isValid')
  1241. ->will($this->returnValue(false));
  1242. $this->expectTranslate('flash_create_error');
  1243. $this->request->setMethod('POST');
  1244. $formView = $this->getMock('Symfony\Component\Form\FormView');
  1245. $form->expects($this->any())
  1246. ->method('createView')
  1247. ->will($this->returnValue($formView));
  1248. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->createAction());
  1249. $this->assertEquals($this->admin, $this->parameters['admin']);
  1250. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1251. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1252. $this->assertEquals('create', $this->parameters['action']);
  1253. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1254. $this->assertEquals($object, $this->parameters['object']);
  1255. $this->assertEquals(array('sonata_flash_error'=>array('flash_create_error')), $this->session->getFlashBag()->all());
  1256. $this->assertEquals('SonataAdminBundle:CRUD:edit.html.twig', $this->template);
  1257. }
  1258. public function testCreateActionAjaxSuccess()
  1259. {
  1260. $object = new \stdClass();
  1261. $this->admin->expects($this->exactly(2))
  1262. ->method('isGranted')
  1263. ->will($this->returnCallback(function ($name, $objectIn = null) use ($object) {
  1264. if ($name != 'CREATE') {
  1265. return false;
  1266. }
  1267. if ($objectIn === null) {
  1268. return true;
  1269. }
  1270. return ($objectIn === $object);
  1271. }));
  1272. $this->admin->expects($this->once())
  1273. ->method('getNewInstance')
  1274. ->will($this->returnValue($object));
  1275. $this->admin->expects($this->once())
  1276. ->method('create')
  1277. ->will($this->returnArgument(0));
  1278. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1279. ->disableOriginalConstructor()
  1280. ->getMock();
  1281. $this->admin->expects($this->once())
  1282. ->method('getForm')
  1283. ->will($this->returnValue($form));
  1284. $form->expects($this->once())
  1285. ->method('isValid')
  1286. ->will($this->returnValue(true));
  1287. $this->admin->expects($this->once())
  1288. ->method('getNormalizedIdentifier')
  1289. ->with($this->equalTo($object))
  1290. ->will($this->returnValue('foo_normalized'));
  1291. $this->request->setMethod('POST');
  1292. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  1293. $response = $this->controller->createAction();
  1294. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
  1295. $this->assertEquals(json_encode(array('result'=>'ok', 'objectId' => 'foo_normalized')), $response->getContent());
  1296. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1297. }
  1298. public function testCreateActionAjaxError()
  1299. {
  1300. $this->admin->expects($this->once())
  1301. ->method('isGranted')
  1302. ->with($this->equalTo('CREATE'))
  1303. ->will($this->returnValue(true));
  1304. $object = new \stdClass();
  1305. $this->admin->expects($this->once())
  1306. ->method('getNewInstance')
  1307. ->will($this->returnValue($object));
  1308. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1309. ->disableOriginalConstructor()
  1310. ->getMock();
  1311. $this->admin->expects($this->once())
  1312. ->method('getForm')
  1313. ->will($this->returnValue($form));
  1314. $form->expects($this->once())
  1315. ->method('isValid')
  1316. ->will($this->returnValue(false));
  1317. $this->request->setMethod('POST');
  1318. $this->request->headers->set('X-Requested-With', 'XMLHttpRequest');
  1319. $formView = $this->getMock('Symfony\Component\Form\FormView');
  1320. $form->expects($this->any())
  1321. ->method('createView')
  1322. ->will($this->returnValue($formView));
  1323. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->createAction());
  1324. $this->assertEquals($this->admin, $this->parameters['admin']);
  1325. $this->assertEquals('SonataAdminBundle::ajax_layout.html.twig', $this->parameters['base_template']);
  1326. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1327. $this->assertEquals('create', $this->parameters['action']);
  1328. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1329. $this->assertEquals($object, $this->parameters['object']);
  1330. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1331. $this->assertEquals('SonataAdminBundle:CRUD:edit.html.twig', $this->template);
  1332. }
  1333. public function testCreateActionWithPreview()
  1334. {
  1335. $this->admin->expects($this->once())
  1336. ->method('isGranted')
  1337. ->with($this->equalTo('CREATE'))
  1338. ->will($this->returnValue(true));
  1339. $object = new \stdClass();
  1340. $this->admin->expects($this->once())
  1341. ->method('getNewInstance')
  1342. ->will($this->returnValue($object));
  1343. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1344. ->disableOriginalConstructor()
  1345. ->getMock();
  1346. $this->admin->expects($this->once())
  1347. ->method('getForm')
  1348. ->will($this->returnValue($form));
  1349. $this->admin->expects($this->once())
  1350. ->method('supportsPreviewMode')
  1351. ->will($this->returnValue(true));
  1352. $formView = $this->getMock('Symfony\Component\Form\FormView');
  1353. $form->expects($this->any())
  1354. ->method('createView')
  1355. ->will($this->returnValue($formView));
  1356. $form->expects($this->once())
  1357. ->method('isValid')
  1358. ->will($this->returnValue(true));
  1359. $this->request->setMethod('POST');
  1360. $this->request->request->set('btn_preview', 'Preview');
  1361. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->createAction());
  1362. $this->assertEquals($this->admin, $this->parameters['admin']);
  1363. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1364. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1365. $this->assertEquals('create', $this->parameters['action']);
  1366. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1367. $this->assertEquals($object, $this->parameters['object']);
  1368. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1369. $this->assertEquals('SonataAdminBundle:CRUD:preview.html.twig', $this->template);
  1370. }
  1371. public function testExportActionAccessDenied()
  1372. {
  1373. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1374. $this->admin->expects($this->once())
  1375. ->method('isGranted')
  1376. ->with($this->equalTo('EXPORT'))
  1377. ->will($this->returnValue(false));
  1378. $this->controller->exportAction($this->request);
  1379. }
  1380. public function testExportActionWrongFormat()
  1381. {
  1382. $this->setExpectedException('RuntimeException', 'Export in format `csv` is not allowed for class: `Foo`. Allowed formats are: `json`');
  1383. $this->admin->expects($this->once())
  1384. ->method('isGranted')
  1385. ->with($this->equalTo('EXPORT'))
  1386. ->will($this->returnValue(true));
  1387. $this->admin->expects($this->once())
  1388. ->method('getExportFormats')
  1389. ->will($this->returnValue(array('json')));
  1390. $this->admin->expects($this->once())
  1391. ->method('getClass')
  1392. ->will($this->returnValue('Foo'));
  1393. $this->request->query->set('format', 'csv');
  1394. $this->controller->exportAction($this->request);
  1395. }
  1396. public function testExportAction()
  1397. {
  1398. $this->admin->expects($this->once())
  1399. ->method('isGranted')
  1400. ->with($this->equalTo('EXPORT'))
  1401. ->will($this->returnValue(true));
  1402. $this->admin->expects($this->once())
  1403. ->method('getExportFormats')
  1404. ->will($this->returnValue(array('json')));
  1405. $dataSourceIterator = $this->getMock('Exporter\Source\SourceIteratorInterface');
  1406. $this->admin->expects($this->once())
  1407. ->method('getDataSourceIterator')
  1408. ->will($this->returnValue($dataSourceIterator));
  1409. $this->request->query->set('format', 'json');
  1410. $response = $this->controller->exportAction($this->request);
  1411. $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response);
  1412. $this->assertEquals(200, $response->getStatusCode());
  1413. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1414. }
  1415. public function testHistoryActionAccessDenied()
  1416. {
  1417. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1418. $this->admin->expects($this->any())
  1419. ->method('getObject')
  1420. ->will($this->returnValue(new \StdClass()));
  1421. $this->admin->expects($this->once())
  1422. ->method('isGranted')
  1423. ->with($this->equalTo('EDIT'))
  1424. ->will($this->returnValue(false));
  1425. $this->controller->historyAction();
  1426. }
  1427. public function testHistoryActionNotFoundException()
  1428. {
  1429. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  1430. $this->admin->expects($this->once())
  1431. ->method('getObject')
  1432. ->will($this->returnValue(false));
  1433. $this->controller->historyAction();
  1434. }
  1435. public function testHistoryActionNoReader()
  1436. {
  1437. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the audit reader for class : Foo');
  1438. $this->request->query->set('id', 123);
  1439. $this->admin->expects($this->once())
  1440. ->method('isGranted')
  1441. ->with($this->equalTo('EDIT'))
  1442. ->will($this->returnValue(true));
  1443. $object = new \stdClass();
  1444. $this->admin->expects($this->once())
  1445. ->method('getObject')
  1446. ->will($this->returnValue($object));
  1447. $this->admin->expects($this->any())
  1448. ->method('getClass')
  1449. ->will($this->returnValue('Foo'));
  1450. $this->auditManager->expects($this->once())
  1451. ->method('hasReader')
  1452. ->with($this->equalTo('Foo'))
  1453. ->will($this->returnValue(false));
  1454. $this->controller->historyAction();
  1455. }
  1456. public function testHistoryAction()
  1457. {
  1458. $this->request->query->set('id', 123);
  1459. $this->admin->expects($this->once())
  1460. ->method('isGranted')
  1461. ->with($this->equalTo('EDIT'))
  1462. ->will($this->returnValue(true));
  1463. $object = new \stdClass();
  1464. $this->admin->expects($this->once())
  1465. ->method('getObject')
  1466. ->will($this->returnValue($object));
  1467. $this->admin->expects($this->any())
  1468. ->method('getClass')
  1469. ->will($this->returnValue('Foo'));
  1470. $this->auditManager->expects($this->once())
  1471. ->method('hasReader')
  1472. ->with($this->equalTo('Foo'))
  1473. ->will($this->returnValue(true));
  1474. $reader = $this->getMock('Sonata\AdminBundle\Model\AuditReaderInterface');
  1475. $this->auditManager->expects($this->once())
  1476. ->method('getReader')
  1477. ->with($this->equalTo('Foo'))
  1478. ->will($this->returnValue($reader));
  1479. $reader->expects($this->once())
  1480. ->method('findRevisions')
  1481. ->with($this->equalTo('Foo'), $this->equalTo(123))
  1482. ->will($this->returnValue(array()));
  1483. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->historyAction());
  1484. $this->assertEquals($this->admin, $this->parameters['admin']);
  1485. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1486. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1487. $this->assertEquals('history', $this->parameters['action']);
  1488. $this->assertEquals(array(), $this->parameters['revisions']);
  1489. $this->assertEquals($object, $this->parameters['object']);
  1490. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1491. $this->assertEquals('SonataAdminBundle:CRUD:history.html.twig', $this->template);
  1492. }
  1493. public function testAclActionAclNotEnabled()
  1494. {
  1495. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'ACL are not enabled for this admin');
  1496. $this->controller->aclAction();
  1497. }
  1498. public function testAclActionNotFoundException()
  1499. {
  1500. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
  1501. $this->admin->expects($this->once())
  1502. ->method('isAclEnabled')
  1503. ->will($this->returnValue(true));
  1504. $this->admin->expects($this->once())
  1505. ->method('getObject')
  1506. ->will($this->returnValue(false));
  1507. $this->controller->aclAction();
  1508. }
  1509. public function testAclActionAccessDenied()
  1510. {
  1511. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1512. $this->admin->expects($this->once())
  1513. ->method('isAclEnabled')
  1514. ->will($this->returnValue(true));
  1515. $object = new \stdClass();
  1516. $this->admin->expects($this->once())
  1517. ->method('getObject')
  1518. ->will($this->returnValue($object));
  1519. $this->admin->expects($this->once())
  1520. ->method('isGranted')
  1521. ->with($this->equalTo('MASTER'), $this->equalTo($object))
  1522. ->will($this->returnValue(false));
  1523. $this->controller->aclAction();
  1524. }
  1525. public function testAclAction()
  1526. {
  1527. $this->request->query->set('id', 123);
  1528. $this->admin->expects($this->once())
  1529. ->method('isAclEnabled')
  1530. ->will($this->returnValue(true));
  1531. $object = new \stdClass();
  1532. $this->admin->expects($this->once())
  1533. ->method('getObject')
  1534. ->will($this->returnValue($object));
  1535. $this->admin->expects($this->any())
  1536. ->method('isGranted')
  1537. ->will($this->returnValue(true));
  1538. $this->adminObjectAclManipulator->expects($this->once())
  1539. ->method('getMaskBuilderClass')
  1540. ->will($this->returnValue('\Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap'));
  1541. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1542. ->disableOriginalConstructor()
  1543. ->getMock();
  1544. $form->expects($this->once())
  1545. ->method('createView')
  1546. ->will($this->returnValue($this->getMock('Symfony\Component\Form\FormView')));
  1547. $this->adminObjectAclManipulator->expects($this->once())
  1548. ->method('createForm')
  1549. ->with($this->isInstanceOf('Sonata\AdminBundle\Util\AdminObjectAclData'))
  1550. ->will($this->returnValue($form));
  1551. $aclSecurityHandler = $this->getMockBuilder('Sonata\AdminBundle\Security\Handler\AclSecurityHandler')
  1552. ->disableOriginalConstructor()
  1553. ->getMock();
  1554. $aclSecurityHandler->expects($this->any())
  1555. ->method('getObjectPermissions')
  1556. ->will($this->returnValue(array()));
  1557. $this->admin->expects($this->any())
  1558. ->method('getSecurityHandler')
  1559. ->will($this->returnValue($aclSecurityHandler));
  1560. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->aclAction());
  1561. $this->assertEquals($this->admin, $this->parameters['admin']);
  1562. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1563. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1564. $this->assertEquals('acl', $this->parameters['action']);
  1565. $this->assertEquals(array(), $this->parameters['permissions']);
  1566. $this->assertEquals($object, $this->parameters['object']);
  1567. $this->assertInstanceOf('\ArrayIterator', $this->parameters['users']);
  1568. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1569. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1570. $this->assertEquals('SonataAdminBundle:CRUD:acl.html.twig', $this->template);
  1571. }
  1572. public function testAclActionInvalidUpdate()
  1573. {
  1574. $this->request->query->set('id', 123);
  1575. $this->admin->expects($this->once())
  1576. ->method('isAclEnabled')
  1577. ->will($this->returnValue(true));
  1578. $object = new \stdClass();
  1579. $this->admin->expects($this->once())
  1580. ->method('getObject')
  1581. ->will($this->returnValue($object));
  1582. $this->admin->expects($this->any())
  1583. ->method('isGranted')
  1584. ->will($this->returnValue(true));
  1585. $this->adminObjectAclManipulator->expects($this->once())
  1586. ->method('getMaskBuilderClass')
  1587. ->will($this->returnValue('\Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap'));
  1588. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1589. ->disableOriginalConstructor()
  1590. ->getMock();
  1591. $form->expects($this->once())
  1592. ->method('isValid')
  1593. ->will($this->returnValue(false));
  1594. $form->expects($this->once())
  1595. ->method('createView')
  1596. ->will($this->returnValue($this->getMock('Symfony\Component\Form\FormView')));
  1597. $this->adminObjectAclManipulator->expects($this->once())
  1598. ->method('createForm')
  1599. ->with($this->isInstanceOf('Sonata\AdminBundle\Util\AdminObjectAclData'))
  1600. ->will($this->returnValue($form));
  1601. $aclSecurityHandler = $this->getMockBuilder('Sonata\AdminBundle\Security\Handler\AclSecurityHandler')
  1602. ->disableOriginalConstructor()
  1603. ->getMock();
  1604. $aclSecurityHandler->expects($this->any())
  1605. ->method('getObjectPermissions')
  1606. ->will($this->returnValue(array()));
  1607. $this->admin->expects($this->any())
  1608. ->method('getSecurityHandler')
  1609. ->will($this->returnValue($aclSecurityHandler));
  1610. $this->request->setMethod('POST');
  1611. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->aclAction());
  1612. $this->assertEquals($this->admin, $this->parameters['admin']);
  1613. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1614. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1615. $this->assertEquals('acl', $this->parameters['action']);
  1616. $this->assertEquals(array(), $this->parameters['permissions']);
  1617. $this->assertEquals($object, $this->parameters['object']);
  1618. $this->assertInstanceOf('\ArrayIterator', $this->parameters['users']);
  1619. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  1620. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1621. $this->assertEquals('SonataAdminBundle:CRUD:acl.html.twig', $this->template);
  1622. }
  1623. public function testAclActionSuccessfulUpdate()
  1624. {
  1625. $this->request->query->set('id', 123);
  1626. $this->admin->expects($this->once())
  1627. ->method('isAclEnabled')
  1628. ->will($this->returnValue(true));
  1629. $object = new \stdClass();
  1630. $this->admin->expects($this->once())
  1631. ->method('getObject')
  1632. ->will($this->returnValue($object));
  1633. $this->admin->expects($this->any())
  1634. ->method('isGranted')
  1635. ->will($this->returnValue(true));
  1636. $this->adminObjectAclManipulator->expects($this->once())
  1637. ->method('getMaskBuilderClass')
  1638. ->will($this->returnValue('\Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap'));
  1639. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  1640. ->disableOriginalConstructor()
  1641. ->getMock();
  1642. $form->expects($this->any())
  1643. ->method('createView')
  1644. ->will($this->returnValue($this->getMock('Symfony\Component\Form\FormView')));
  1645. $form->expects($this->once())
  1646. ->method('isValid')
  1647. ->will($this->returnValue(true));
  1648. $this->adminObjectAclManipulator->expects($this->once())
  1649. ->method('createForm')
  1650. ->with($this->isInstanceOf('Sonata\AdminBundle\Util\AdminObjectAclData'))
  1651. ->will($this->returnValue($form));
  1652. $aclSecurityHandler = $this->getMockBuilder('Sonata\AdminBundle\Security\Handler\AclSecurityHandler')
  1653. ->disableOriginalConstructor()
  1654. ->getMock();
  1655. $aclSecurityHandler->expects($this->any())
  1656. ->method('getObjectPermissions')
  1657. ->will($this->returnValue(array()));
  1658. $this->admin->expects($this->any())
  1659. ->method('getSecurityHandler')
  1660. ->will($this->returnValue($aclSecurityHandler));
  1661. $this->request->setMethod('POST');
  1662. $response = $this->controller->aclAction();
  1663. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
  1664. $this->assertSame(array('flash_acl_edit_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  1665. $this->assertEquals('stdClass_acl', $response->getTargetUrl());
  1666. }
  1667. public function testHistoryViewRevisionActionAccessDenied()
  1668. {
  1669. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1670. $this->admin->expects($this->any())
  1671. ->method('getObject')
  1672. ->will($this->returnValue(new \StdClass()));
  1673. $this->admin->expects($this->once())
  1674. ->method('isGranted')
  1675. ->with($this->equalTo('EDIT'))
  1676. ->will($this->returnValue(false));
  1677. $this->controller->historyViewRevisionAction();
  1678. }
  1679. public function testHistoryViewRevisionActionNotFoundException()
  1680. {
  1681. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the object with id : 123');
  1682. $this->request->query->set('id', 123);
  1683. $this->admin->expects($this->once())
  1684. ->method('getObject')
  1685. ->will($this->returnValue(false));
  1686. $this->controller->historyViewRevisionAction();
  1687. }
  1688. public function testHistoryViewRevisionActionNoReader()
  1689. {
  1690. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the audit reader for class : Foo');
  1691. $this->request->query->set('id', 123);
  1692. $this->admin->expects($this->once())
  1693. ->method('isGranted')
  1694. ->with($this->equalTo('EDIT'))
  1695. ->will($this->returnValue(true));
  1696. $object = new \stdClass();
  1697. $this->admin->expects($this->once())
  1698. ->method('getObject')
  1699. ->will($this->returnValue($object));
  1700. $this->admin->expects($this->any())
  1701. ->method('getClass')
  1702. ->will($this->returnValue('Foo'));
  1703. $this->auditManager->expects($this->once())
  1704. ->method('hasReader')
  1705. ->with($this->equalTo('Foo'))
  1706. ->will($this->returnValue(false));
  1707. $this->controller->historyViewRevisionAction();
  1708. }
  1709. public function testHistoryViewRevisionActionNotFoundRevision()
  1710. {
  1711. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the targeted object `123` from the revision `456` with classname : `Foo`');
  1712. $this->request->query->set('id', 123);
  1713. $this->admin->expects($this->once())
  1714. ->method('isGranted')
  1715. ->with($this->equalTo('EDIT'))
  1716. ->will($this->returnValue(true));
  1717. $object = new \stdClass();
  1718. $this->admin->expects($this->once())
  1719. ->method('getObject')
  1720. ->will($this->returnValue($object));
  1721. $this->admin->expects($this->any())
  1722. ->method('getClass')
  1723. ->will($this->returnValue('Foo'));
  1724. $this->auditManager->expects($this->once())
  1725. ->method('hasReader')
  1726. ->with($this->equalTo('Foo'))
  1727. ->will($this->returnValue(true));
  1728. $reader = $this->getMock('Sonata\AdminBundle\Model\AuditReaderInterface');
  1729. $this->auditManager->expects($this->once())
  1730. ->method('getReader')
  1731. ->with($this->equalTo('Foo'))
  1732. ->will($this->returnValue($reader));
  1733. $reader->expects($this->once())
  1734. ->method('find')
  1735. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(456))
  1736. ->will($this->returnValue(null));
  1737. $this->controller->historyViewRevisionAction(123, 456);
  1738. }
  1739. public function testHistoryViewRevisionAction()
  1740. {
  1741. $this->request->query->set('id', 123);
  1742. $this->admin->expects($this->once())
  1743. ->method('isGranted')
  1744. ->with($this->equalTo('EDIT'))
  1745. ->will($this->returnValue(true));
  1746. $object = new \stdClass();
  1747. $this->admin->expects($this->once())
  1748. ->method('getObject')
  1749. ->will($this->returnValue($object));
  1750. $this->admin->expects($this->any())
  1751. ->method('getClass')
  1752. ->will($this->returnValue('Foo'));
  1753. $this->auditManager->expects($this->once())
  1754. ->method('hasReader')
  1755. ->with($this->equalTo('Foo'))
  1756. ->will($this->returnValue(true));
  1757. $reader = $this->getMock('Sonata\AdminBundle\Model\AuditReaderInterface');
  1758. $this->auditManager->expects($this->once())
  1759. ->method('getReader')
  1760. ->with($this->equalTo('Foo'))
  1761. ->will($this->returnValue($reader));
  1762. $objectRevision = new \stdClass();
  1763. $objectRevision->revision = 456;
  1764. $reader->expects($this->once())
  1765. ->method('find')
  1766. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(456))
  1767. ->will($this->returnValue($objectRevision));
  1768. $this->admin->expects($this->once())
  1769. ->method('setSubject')
  1770. ->with($this->equalTo($objectRevision))
  1771. ->will($this->returnValue(null));
  1772. $fieldDescriptionCollection = new FieldDescriptionCollection();
  1773. $this->admin->expects($this->once())
  1774. ->method('getShow')
  1775. ->will($this->returnValue($fieldDescriptionCollection));
  1776. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->historyViewRevisionAction(123, 456));
  1777. $this->assertEquals($this->admin, $this->parameters['admin']);
  1778. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1779. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1780. $this->assertEquals('show', $this->parameters['action']);
  1781. $this->assertEquals($objectRevision, $this->parameters['object']);
  1782. $this->assertEquals($fieldDescriptionCollection, $this->parameters['elements']);
  1783. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1784. $this->assertEquals('SonataAdminBundle:CRUD:show.html.twig', $this->template);
  1785. }
  1786. public function testhistoryCompareRevisionsActionAccessDenied()
  1787. {
  1788. $this->setExpectedException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
  1789. $this->admin->expects($this->once())
  1790. ->method('isGranted')
  1791. ->with($this->equalTo('EDIT'))
  1792. ->will($this->returnValue(false));
  1793. $this->controller->historyCompareRevisionsAction();
  1794. }
  1795. public function testhistoryCompareRevisionsActionNotFoundException()
  1796. {
  1797. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the object with id : 123');
  1798. $this->request->query->set('id', 123);
  1799. $this->admin->expects($this->once())
  1800. ->method('isGranted')
  1801. ->with($this->equalTo('EDIT'))
  1802. ->will($this->returnValue(true));
  1803. $this->admin->expects($this->once())
  1804. ->method('getObject')
  1805. ->will($this->returnValue(false));
  1806. $this->controller->historyCompareRevisionsAction();
  1807. }
  1808. public function testhistoryCompareRevisionsActionNoReader()
  1809. {
  1810. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the audit reader for class : Foo');
  1811. $this->request->query->set('id', 123);
  1812. $this->admin->expects($this->once())
  1813. ->method('isGranted')
  1814. ->with($this->equalTo('EDIT'))
  1815. ->will($this->returnValue(true));
  1816. $object = new \stdClass();
  1817. $this->admin->expects($this->once())
  1818. ->method('getObject')
  1819. ->will($this->returnValue($object));
  1820. $this->admin->expects($this->any())
  1821. ->method('getClass')
  1822. ->will($this->returnValue('Foo'));
  1823. $this->auditManager->expects($this->once())
  1824. ->method('hasReader')
  1825. ->with($this->equalTo('Foo'))
  1826. ->will($this->returnValue(false));
  1827. $this->controller->historyCompareRevisionsAction();
  1828. }
  1829. public function testhistoryCompareRevisionsActionNotFoundBaseRevision()
  1830. {
  1831. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the targeted object `123` from the revision `456` with classname : `Foo`');
  1832. $this->request->query->set('id', 123);
  1833. $this->admin->expects($this->once())
  1834. ->method('isGranted')
  1835. ->with($this->equalTo('EDIT'))
  1836. ->will($this->returnValue(true));
  1837. $object = new \stdClass();
  1838. $this->admin->expects($this->once())
  1839. ->method('getObject')
  1840. ->will($this->returnValue($object));
  1841. $this->admin->expects($this->any())
  1842. ->method('getClass')
  1843. ->will($this->returnValue('Foo'));
  1844. $this->auditManager->expects($this->once())
  1845. ->method('hasReader')
  1846. ->with($this->equalTo('Foo'))
  1847. ->will($this->returnValue(true));
  1848. $reader = $this->getMock('Sonata\AdminBundle\Model\AuditReaderInterface');
  1849. $this->auditManager->expects($this->once())
  1850. ->method('getReader')
  1851. ->with($this->equalTo('Foo'))
  1852. ->will($this->returnValue($reader));
  1853. // once because it will not be found and therefore the second call won't be executed
  1854. $reader->expects($this->once())
  1855. ->method('find')
  1856. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(456))
  1857. ->will($this->returnValue(null));
  1858. $this->controller->historyCompareRevisionsAction(123, 456, 789);
  1859. }
  1860. public function testhistoryCompareRevisionsActionNotFoundCompareRevision()
  1861. {
  1862. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'unable to find the targeted object `123` from the revision `789` with classname : `Foo`');
  1863. $this->request->query->set('id', 123);
  1864. $this->admin->expects($this->once())
  1865. ->method('isGranted')
  1866. ->with($this->equalTo('EDIT'))
  1867. ->will($this->returnValue(true));
  1868. $object = new \stdClass();
  1869. $this->admin->expects($this->once())
  1870. ->method('getObject')
  1871. ->will($this->returnValue($object));
  1872. $this->admin->expects($this->any())
  1873. ->method('getClass')
  1874. ->will($this->returnValue('Foo'));
  1875. $this->auditManager->expects($this->once())
  1876. ->method('hasReader')
  1877. ->with($this->equalTo('Foo'))
  1878. ->will($this->returnValue(true));
  1879. $reader = $this->getMock('Sonata\AdminBundle\Model\AuditReaderInterface');
  1880. $this->auditManager->expects($this->once())
  1881. ->method('getReader')
  1882. ->with($this->equalTo('Foo'))
  1883. ->will($this->returnValue($reader));
  1884. $objectRevision = new \stdClass();
  1885. $objectRevision->revision = 456;
  1886. // first call should return, so the second call will throw an exception
  1887. $reader->expects($this->at(0))
  1888. ->method('find')
  1889. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(456))
  1890. ->will($this->returnValue($objectRevision));
  1891. $reader->expects($this->at(1))
  1892. ->method('find')
  1893. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(789))
  1894. ->will($this->returnValue(null));
  1895. $this->controller->historyCompareRevisionsAction(123, 456, 789);
  1896. }
  1897. public function testhistoryCompareRevisionsActionAction()
  1898. {
  1899. $this->request->query->set('id', 123);
  1900. $this->admin->expects($this->once())
  1901. ->method('isGranted')
  1902. ->with($this->equalTo('EDIT'))
  1903. ->will($this->returnValue(true));
  1904. $object = new \stdClass();
  1905. $this->admin->expects($this->once())
  1906. ->method('getObject')
  1907. ->will($this->returnValue($object));
  1908. $this->admin->expects($this->any())
  1909. ->method('getClass')
  1910. ->will($this->returnValue('Foo'));
  1911. $this->auditManager->expects($this->once())
  1912. ->method('hasReader')
  1913. ->with($this->equalTo('Foo'))
  1914. ->will($this->returnValue(true));
  1915. $reader = $this->getMock('Sonata\AdminBundle\Model\AuditReaderInterface');
  1916. $this->auditManager->expects($this->once())
  1917. ->method('getReader')
  1918. ->with($this->equalTo('Foo'))
  1919. ->will($this->returnValue($reader));
  1920. $objectRevision = new \stdClass();
  1921. $objectRevision->revision = 456;
  1922. $compareObjectRevision = new \stdClass();
  1923. $compareObjectRevision->revision = 789;
  1924. $reader->expects($this->at(0))
  1925. ->method('find')
  1926. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(456))
  1927. ->will($this->returnValue($objectRevision));
  1928. $reader->expects($this->at(1))
  1929. ->method('find')
  1930. ->with($this->equalTo('Foo'), $this->equalTo(123), $this->equalTo(789))
  1931. ->will($this->returnValue($compareObjectRevision));
  1932. $this->admin->expects($this->once())
  1933. ->method('setSubject')
  1934. ->with($this->equalTo($objectRevision))
  1935. ->will($this->returnValue(null));
  1936. $fieldDescriptionCollection = new FieldDescriptionCollection();
  1937. $this->admin->expects($this->once())
  1938. ->method('getShow')
  1939. ->will($this->returnValue($fieldDescriptionCollection));
  1940. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->historyCompareRevisionsAction(123, 456, 789));
  1941. $this->assertEquals($this->admin, $this->parameters['admin']);
  1942. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  1943. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  1944. $this->assertEquals('show', $this->parameters['action']);
  1945. $this->assertEquals($objectRevision, $this->parameters['object']);
  1946. $this->assertEquals($compareObjectRevision, $this->parameters['object_compare']);
  1947. $this->assertEquals($fieldDescriptionCollection, $this->parameters['elements']);
  1948. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  1949. $this->assertEquals('SonataAdminBundle:CRUD:show_compare.html.twig', $this->template);
  1950. }
  1951. public function testBatchActionWrongMethod()
  1952. {
  1953. $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'Invalid request type "GET", POST expected');
  1954. $this->controller->batchAction();
  1955. }
  1956. public function testBatchActionActionNotDefined()
  1957. {
  1958. $this->setExpectedException('RuntimeException', 'The `foo` batch action is not defined');
  1959. $batchActions = array();
  1960. $this->admin->expects($this->once())
  1961. ->method('getBatchActions')
  1962. ->will($this->returnValue($batchActions));
  1963. $this->request->setMethod('POST');
  1964. $this->request->request->set('data', json_encode(array('action'=>'foo', 'idx'=>array('123', '456'), 'all_elements'=>false)));
  1965. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  1966. $this->controller->batchAction();
  1967. }
  1968. public function testBatchActionActionInvalidCsrfToken()
  1969. {
  1970. $this->request->setMethod('POST');
  1971. $this->request->request->set('data', json_encode(array('action'=>'foo', 'idx'=>array('123', '456'), 'all_elements'=>false)));
  1972. $this->request->request->set('_sonata_csrf_token', 'CSRF-INVALID');
  1973. try {
  1974. $this->controller->batchAction();
  1975. } catch (HttpException $e) {
  1976. $this->assertEquals('The csrf token is not valid, CSRF attack?', $e->getMessage());
  1977. $this->assertEquals(400, $e->getStatusCode());
  1978. }
  1979. }
  1980. public function testBatchActionMethodNotExist()
  1981. {
  1982. $this->setExpectedException('RuntimeException', 'A `Sonata\AdminBundle\Controller\CRUDController::batchActionFoo` method must be created');
  1983. $batchActions = array('foo'=>array('label'=>'Foo Bar', 'ask_confirmation' => false));
  1984. $this->admin->expects($this->once())
  1985. ->method('getBatchActions')
  1986. ->will($this->returnValue($batchActions));
  1987. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  1988. $this->admin->expects($this->once())
  1989. ->method('getDatagrid')
  1990. ->will($this->returnValue($datagrid));
  1991. $this->request->setMethod('POST');
  1992. $this->request->request->set('data', json_encode(array('action'=>'foo', 'idx'=>array('123', '456'), 'all_elements'=>false)));
  1993. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  1994. $this->controller->batchAction();
  1995. }
  1996. public function testBatchActionWithoutConfirmation()
  1997. {
  1998. $batchActions = array('delete'=>array('label'=>'Foo Bar', 'ask_confirmation' => false));
  1999. $this->admin->expects($this->once())
  2000. ->method('getBatchActions')
  2001. ->will($this->returnValue($batchActions));
  2002. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2003. $query = $this->getMock('\Sonata\AdminBundle\Datagrid\ProxyQueryInterface');
  2004. $datagrid->expects($this->once())
  2005. ->method('getQuery')
  2006. ->will($this->returnValue($query));
  2007. $this->admin->expects($this->once())
  2008. ->method('getDatagrid')
  2009. ->will($this->returnValue($datagrid));
  2010. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  2011. $this->admin->expects($this->once())
  2012. ->method('isGranted')
  2013. ->with($this->equalTo('DELETE'))
  2014. ->will($this->returnValue(true));
  2015. $this->admin->expects($this->any())
  2016. ->method('getModelManager')
  2017. ->will($this->returnValue($modelManager));
  2018. $this->admin->expects($this->any())
  2019. ->method('getClass')
  2020. ->will($this->returnValue('Foo'));
  2021. $modelManager->expects($this->once())
  2022. ->method('addIdentifiersToQuery')
  2023. ->with($this->equalTo('Foo'), $this->equalTo($query), $this->equalTo(array('123', '456')))
  2024. ->will($this->returnValue(true));
  2025. $this->request->setMethod('POST');
  2026. $this->request->request->set('data', json_encode(array('action'=>'delete', 'idx'=>array('123', '456'), 'all_elements'=>false)));
  2027. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2028. $result = $this->controller->batchAction();
  2029. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  2030. $this->assertSame(array('flash_batch_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  2031. $this->assertEquals('list?', $result->getTargetUrl());
  2032. }
  2033. public function testBatchActionWithoutConfirmation2()
  2034. {
  2035. $batchActions = array('delete'=>array('label'=>'Foo Bar', 'ask_confirmation' => false));
  2036. $this->admin->expects($this->once())
  2037. ->method('getBatchActions')
  2038. ->will($this->returnValue($batchActions));
  2039. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2040. $query = $this->getMock('\Sonata\AdminBundle\Datagrid\ProxyQueryInterface');
  2041. $datagrid->expects($this->once())
  2042. ->method('getQuery')
  2043. ->will($this->returnValue($query));
  2044. $this->admin->expects($this->once())
  2045. ->method('getDatagrid')
  2046. ->will($this->returnValue($datagrid));
  2047. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  2048. $this->admin->expects($this->once())
  2049. ->method('isGranted')
  2050. ->with($this->equalTo('DELETE'))
  2051. ->will($this->returnValue(true));
  2052. $this->admin->expects($this->any())
  2053. ->method('getModelManager')
  2054. ->will($this->returnValue($modelManager));
  2055. $this->admin->expects($this->any())
  2056. ->method('getClass')
  2057. ->will($this->returnValue('Foo'));
  2058. $modelManager->expects($this->once())
  2059. ->method('addIdentifiersToQuery')
  2060. ->with($this->equalTo('Foo'), $this->equalTo($query), $this->equalTo(array('123', '456')))
  2061. ->will($this->returnValue(true));
  2062. $this->request->setMethod('POST');
  2063. $this->request->request->set('action', 'delete');
  2064. $this->request->request->set('idx', array('123', '456'));
  2065. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2066. $result = $this->controller->batchAction();
  2067. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  2068. $this->assertSame(array('flash_batch_delete_success'), $this->session->getFlashBag()->get('sonata_flash_success'));
  2069. $this->assertEquals('list?', $result->getTargetUrl());
  2070. }
  2071. public function testBatchActionWithConfirmation()
  2072. {
  2073. $batchActions = array('delete'=>array('label'=>'Foo Bar', 'ask_confirmation' => true));
  2074. $this->admin->expects($this->once())
  2075. ->method('getBatchActions')
  2076. ->will($this->returnValue($batchActions));
  2077. $this->admin->expects($this->once())
  2078. ->method('getTranslationLabel')
  2079. ->with($this->equalTo('delete'), $this->equalTo('action'))
  2080. ->will($this->returnValue('delete_action'));
  2081. $data = array('action'=>'delete', 'idx'=>array('123', '456'), 'all_elements'=>false);
  2082. $this->request->setMethod('POST');
  2083. $this->request->request->set('data', json_encode($data));
  2084. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2085. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2086. $this->admin->expects($this->once())
  2087. ->method('getDatagrid')
  2088. ->will($this->returnValue($datagrid));
  2089. $form = $this->getMockBuilder('Symfony\Component\Form\Form')
  2090. ->disableOriginalConstructor()
  2091. ->getMock();
  2092. $form->expects($this->once())
  2093. ->method('createView')
  2094. ->will($this->returnValue($this->getMock('Symfony\Component\Form\FormView')));
  2095. $datagrid->expects($this->once())
  2096. ->method('getForm')
  2097. ->will($this->returnValue($form));
  2098. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $this->controller->batchAction());
  2099. $this->assertEquals($this->admin, $this->parameters['admin']);
  2100. $this->assertEquals('SonataAdminBundle::standard_layout.html.twig', $this->parameters['base_template']);
  2101. $this->assertEquals($this->pool, $this->parameters['admin_pool']);
  2102. $this->assertEquals('list', $this->parameters['action']);
  2103. $this->assertEquals($datagrid, $this->parameters['datagrid']);
  2104. $this->assertInstanceOf('Symfony\Component\Form\FormView', $this->parameters['form']);
  2105. $this->assertEquals($data, $this->parameters['data']);
  2106. $this->assertEquals('csrf-token-123_sonata.batch', $this->parameters['csrf_token']);
  2107. $this->assertEquals(array(), $this->session->getFlashBag()->all());
  2108. $this->assertEquals('SonataAdminBundle:CRUD:batch_confirmation.html.twig', $this->template);
  2109. }
  2110. public function testBatchActionNonRelevantAction()
  2111. {
  2112. $controller = new BatchAdminController();
  2113. $controller->setContainer($this->container);
  2114. $batchActions = array('foo'=>array('label'=>'Foo Bar', 'ask_confirmation' => false));
  2115. $this->admin->expects($this->once())
  2116. ->method('getBatchActions')
  2117. ->will($this->returnValue($batchActions));
  2118. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2119. $this->admin->expects($this->once())
  2120. ->method('getDatagrid')
  2121. ->will($this->returnValue($datagrid));
  2122. $this->request->setMethod('POST');
  2123. $this->request->request->set('action', 'foo');
  2124. $this->request->request->set('idx', array('789'));
  2125. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2126. $result = $controller->batchAction();
  2127. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  2128. $this->assertSame(array('flash_batch_empty'), $this->session->getFlashBag()->get('sonata_flash_info'));
  2129. $this->assertEquals('list?', $result->getTargetUrl());
  2130. }
  2131. public function testBatchActionNonRelevantAction2()
  2132. {
  2133. $controller = new BatchAdminController();
  2134. $controller->setContainer($this->container);
  2135. $batchActions = array('foo'=>array('label'=>'Foo Bar', 'ask_confirmation' => false));
  2136. $this->admin->expects($this->once())
  2137. ->method('getBatchActions')
  2138. ->will($this->returnValue($batchActions));
  2139. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2140. $this->admin->expects($this->once())
  2141. ->method('getDatagrid')
  2142. ->will($this->returnValue($datagrid));
  2143. $this->request->setMethod('POST');
  2144. $this->request->request->set('action', 'foo');
  2145. $this->request->request->set('idx', array('999'));
  2146. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2147. $result = $controller->batchAction();
  2148. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  2149. $this->assertSame(array('flash_foo_error'), $this->session->getFlashBag()->get('sonata_flash_info'));
  2150. $this->assertEquals('list?', $result->getTargetUrl());
  2151. }
  2152. public function testBatchActionNoItems()
  2153. {
  2154. $batchActions = array('delete'=>array('label'=>'Foo Bar', 'ask_confirmation' => true));
  2155. $this->admin->expects($this->once())
  2156. ->method('getBatchActions')
  2157. ->will($this->returnValue($batchActions));
  2158. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2159. $this->admin->expects($this->once())
  2160. ->method('getDatagrid')
  2161. ->will($this->returnValue($datagrid));
  2162. $this->request->setMethod('POST');
  2163. $this->request->request->set('action', 'delete');
  2164. $this->request->request->set('idx', array());
  2165. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2166. $result = $this->controller->batchAction();
  2167. $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
  2168. $this->assertSame(array('flash_batch_empty'), $this->session->getFlashBag()->get('sonata_flash_info'));
  2169. $this->assertEquals('list?', $result->getTargetUrl());
  2170. }
  2171. public function testBatchActionNoItemsEmptyQuery()
  2172. {
  2173. $controller = new BatchAdminController();
  2174. $controller->setContainer($this->container);
  2175. $batchActions = array('bar'=>array('label'=>'Foo Bar', 'ask_confirmation' => false));
  2176. $this->admin->expects($this->once())
  2177. ->method('getBatchActions')
  2178. ->will($this->returnValue($batchActions));
  2179. $datagrid = $this->getMock('\Sonata\AdminBundle\Datagrid\DatagridInterface');
  2180. $query = $this->getMock('\Sonata\AdminBundle\Datagrid\ProxyQueryInterface');
  2181. $datagrid->expects($this->once())
  2182. ->method('getQuery')
  2183. ->will($this->returnValue($query));
  2184. $this->admin->expects($this->once())
  2185. ->method('getDatagrid')
  2186. ->will($this->returnValue($datagrid));
  2187. $modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
  2188. $this->admin->expects($this->any())
  2189. ->method('getModelManager')
  2190. ->will($this->returnValue($modelManager));
  2191. $this->admin->expects($this->any())
  2192. ->method('getClass')
  2193. ->will($this->returnValue('Foo'));
  2194. $this->request->setMethod('POST');
  2195. $this->request->request->set('action', 'bar');
  2196. $this->request->request->set('idx', array());
  2197. $this->request->request->set('_sonata_csrf_token', 'csrf-token-123_sonata.batch');
  2198. $result = $controller->batchAction();
  2199. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $result);
  2200. $this->assertEquals('batchActionBar executed', $result->getContent());
  2201. }
  2202. public function getCsrfProvider()
  2203. {
  2204. return $this->csrfProvider;
  2205. }
  2206. private function expectTranslate()
  2207. {
  2208. $args = func_get_args();
  2209. // creates equalTo of all arguments passed to this function
  2210. $phpunit = $this; // PHP 5.3 compatibility
  2211. $argsCheck = array_map(function ($item) use ($phpunit) {
  2212. return $phpunit->equalTo($item);
  2213. }, func_get_args());
  2214. $mock = $this->admin->expects($this->once())->method('trans');
  2215. // passes all arguments to the 'with' of the $admin->trans method
  2216. $mock = call_user_func_array(array($mock, 'with'), $argsCheck);
  2217. $mock->will($this->returnValue($args[0]));
  2218. }
  2219. }