CRUDControllerTest.php 111 KB

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