CRUDControllerTest.php 132 KB

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