/Tests/DependencyInjection/Compiler/ExtensionCompilerPassTest.php

https://github.com/dcsg/SonataAdminBundle · PHP · 328 lines · 227 code · 55 blank · 46 comment · 0 complexity · f99c493d752afb09ae474183f44996dc MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Sonata package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Tests\DependencyInjection;
  11. use Sonata\AdminBundle\DependencyInjection\SonataAdminExtension;
  12. use Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Sonata\AdminBundle\Admin\Admin;
  15. class ExtensionCompilerPassTest extends \PHPUnit_Framework_TestCase
  16. {
  17. /** @var SonataAdminExtension $extension */
  18. private $extension;
  19. /** @var array $config */
  20. private $config;
  21. private $publishExtension;
  22. private $historyExtension;
  23. private $orderExtension;
  24. /**
  25. * Root name of the configuration
  26. *
  27. * @var string
  28. */
  29. private $root;
  30. public function setUp()
  31. {
  32. parent::setUp();
  33. $this->extension = new SonataAdminExtension();
  34. $this->config = $this->getConfig();
  35. $this->root = "sonata.admin";
  36. $this->publishExtension = $this->getMock('Sonata\AdminBundle\Admin\AdminExtensionInterface');
  37. $this->historyExtension = $this->getMock('Sonata\AdminBundle\Admin\AdminExtensionInterface');
  38. $this->orderExtension = $this->getMock('Sonata\AdminBundle\Admin\AdminExtensionInterface');
  39. }
  40. /**
  41. * @covers Sonata\AdminBundle\DependencyInjection\SonataAdminExtension::load
  42. */
  43. public function testAdminExtensionLoad()
  44. {
  45. $this->extension->load(array(), $container = $this->getContainer());
  46. $this->assertTrue($container->hasParameter($this->root . ".extension.map"));
  47. $this->assertTrue(is_array($extensionMap = $container->getParameter($this->root . ".extension.map")));
  48. $this->assertArrayHasKey('admins', $extensionMap);
  49. $this->assertArrayHasKey('excludes', $extensionMap);
  50. $this->assertArrayHasKey('implements', $extensionMap);
  51. $this->assertArrayHasKey('extends', $extensionMap);
  52. $this->assertArrayHasKey('instanceof', $extensionMap);
  53. }
  54. /**
  55. * @covers Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass::flattenExtensionConfiguration
  56. */
  57. public function testFlattenEmptyExtensionConfiguration()
  58. {
  59. $this->extension->load(array(), $container = $this->getContainer());
  60. $extensionMap = $container->getParameter($this->root . ".extension.map");
  61. $method = new \ReflectionMethod(
  62. 'Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass', 'flattenExtensionConfiguration'
  63. );
  64. $method->setAccessible(TRUE);
  65. $extensionMap = $method->invokeArgs(new ExtensionCompilerPass(), array($extensionMap));
  66. $this->assertArrayHasKey('admins', $extensionMap);
  67. $this->assertArrayHasKey('excludes', $extensionMap);
  68. $this->assertArrayHasKey('implements', $extensionMap);
  69. $this->assertArrayHasKey('extends', $extensionMap);
  70. $this->assertArrayHasKey('instanceof', $extensionMap);
  71. $this->assertEmpty($extensionMap['admins']);
  72. $this->assertEmpty($extensionMap['excludes']);
  73. $this->assertEmpty($extensionMap['implements']);
  74. $this->assertEmpty($extensionMap['extends']);
  75. $this->assertEmpty($extensionMap['instanceof']);
  76. }
  77. /**
  78. * @covers Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass::flattenExtensionConfiguration
  79. */
  80. public function testFlattenExtensionConfiguration()
  81. {
  82. $config = $this->getConfig();
  83. $this->extension->load(array($config), $container = $this->getContainer());
  84. $extensionMap = $container->getParameter($this->root . ".extension.map");
  85. $method = new \ReflectionMethod(
  86. 'Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass', 'flattenExtensionConfiguration'
  87. );
  88. $method->setAccessible(TRUE);
  89. $extensionMap = $method->invokeArgs(new ExtensionCompilerPass(), array($extensionMap));
  90. // Admins
  91. $this->assertArrayHasKey('admins', $extensionMap);
  92. $this->assertCount(1, $extensionMap['admins']);
  93. $this->assertContains('sonata_extension_publish', $extensionMap['admins']['sonata_post_admin']);
  94. $this->assertCount(1, $extensionMap['admins']['sonata_post_admin']);
  95. // Excludes
  96. $this->assertArrayHasKey('excludes', $extensionMap);
  97. $this->assertCount(2, $extensionMap['excludes']);
  98. $this->assertArrayHasKey('sonata_article_admin', $extensionMap['excludes']);
  99. $this->assertCount(1, $extensionMap['excludes']['sonata_article_admin']);
  100. $this->assertContains('sonata_extension_history', $extensionMap['excludes']['sonata_article_admin']);
  101. $this->assertArrayHasKey('sonata_post_admin', $extensionMap['excludes']);
  102. $this->assertCount(1, $extensionMap['excludes']['sonata_post_admin']);
  103. $this->assertContains('sonata_extension_order', $extensionMap['excludes']['sonata_post_admin']);
  104. // Implements
  105. $this->assertArrayHasKey('implements', $extensionMap);
  106. $this->assertCount(1, $extensionMap['implements']);
  107. $this->assertArrayHasKey('Sonata\AdminBundle\Tests\DependencyInjection\Publishable', $extensionMap['implements']);
  108. $this->assertCount(2, $extensionMap['implements']['Sonata\AdminBundle\Tests\DependencyInjection\Publishable']);
  109. $this->assertContains('sonata_extension_publish', $extensionMap['implements']['Sonata\AdminBundle\Tests\DependencyInjection\Publishable']);
  110. $this->assertContains('sonata_extension_order', $extensionMap['implements']['Sonata\AdminBundle\Tests\DependencyInjection\Publishable']);
  111. // Extends
  112. $this->assertArrayHasKey('extends', $extensionMap);
  113. $this->assertCount(1, $extensionMap['extends']);
  114. $this->assertArrayHasKey('Sonata\AdminBundle\Tests\DependencyInjection\Post', $extensionMap['extends']);
  115. $this->assertCount(1, $extensionMap['extends']['Sonata\AdminBundle\Tests\DependencyInjection\Post']);
  116. $this->assertContains('sonata_extension_order', $extensionMap['extends']['Sonata\AdminBundle\Tests\DependencyInjection\Post']);
  117. // Instanceof
  118. $this->assertArrayHasKey('instanceof', $extensionMap);
  119. $this->assertCount(1, $extensionMap['instanceof']);
  120. $this->assertArrayHasKey('Sonata\AdminBundle\Tests\DependencyInjection\Post', $extensionMap['instanceof']);
  121. $this->assertCount(1, $extensionMap['instanceof']['Sonata\AdminBundle\Tests\DependencyInjection\Post']);
  122. $this->assertContains('sonata_extension_history', $extensionMap['instanceof']['Sonata\AdminBundle\Tests\DependencyInjection\Post']);
  123. }
  124. /**
  125. * @covers Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass::process
  126. * @expectedException \InvalidArgumentException
  127. */
  128. public function testProcessWithInvalidExtensionId()
  129. {
  130. $config = array(
  131. 'extensions' => array(
  132. 'sonata_extension_unknown' => array(
  133. 'excludes' => array('sonata_article_admin'),
  134. 'instanceof' => array('Sonata\AdminBundle\Tests\DependencyInjection\Post'),
  135. ),
  136. )
  137. );
  138. $container = $this->getContainer();
  139. $this->extension->load(array($config), $container);
  140. $extensionsPass = new ExtensionCompilerPass();
  141. $extensionsPass->process($container);
  142. $container->compile();
  143. }
  144. /**
  145. * @covers Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass::process
  146. */
  147. public function testProcessWithInvalidAdminId()
  148. {
  149. $config = array(
  150. 'extensions' => array(
  151. 'sonata_extension_publish' => array(
  152. 'admins' => array('sonata_unknown_admin'),
  153. 'implements' => array('Sonata\AdminBundle\Tests\DependencyInjection\Publishable'),
  154. ),
  155. )
  156. );
  157. $container = $this->getContainer();
  158. $this->extension->load(array($config), $container);
  159. $extensionsPass = new ExtensionCompilerPass();
  160. $extensionsPass->process($container);
  161. $container->compile();
  162. // nothing should fail the extension just isn't added to the 'sonata_unknown_admin'
  163. }
  164. /**
  165. * @covers Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass::process
  166. */
  167. public function testProcess()
  168. {
  169. $container = $this->getContainer();
  170. $this->extension->load(array($this->config), $container);
  171. $extensionsPass = new ExtensionCompilerPass();
  172. $extensionsPass->process($container);
  173. $container->compile();
  174. $this->assertTrue($container->hasDefinition('sonata_extension_publish'));
  175. $this->assertTrue($container->hasDefinition('sonata_extension_history'));
  176. $this->assertTrue($container->hasDefinition('sonata_extension_order'));
  177. $this->assertTrue($container->hasDefinition('sonata_post_admin'));
  178. $this->assertTrue($container->hasDefinition('sonata_article_admin'));
  179. $this->assertTrue($container->hasDefinition('sonata_news_admin'));
  180. $def = $container->get('sonata_post_admin');
  181. $extensions = $def->getExtensions();
  182. $this->assertCount(2, $extensions);
  183. $this->assertInstanceOf(get_class($this->publishExtension), $extensions[0]);
  184. $this->assertInstanceOf(get_class($this->historyExtension), $extensions[1]);
  185. $def = $container->get('sonata_article_admin');
  186. $extensions = $def->getExtensions();
  187. $this->assertCount(2, $extensions);
  188. $this->assertInstanceOf(get_class($this->publishExtension), $extensions[0]);
  189. $this->assertInstanceOf(get_class($this->orderExtension), $extensions[1]);
  190. $def = $container->get('sonata_news_admin');
  191. $extensions = $def->getExtensions();
  192. $this->assertCount(2, $extensions);
  193. $this->assertInstanceOf(get_class($this->orderExtension), $extensions[0]);
  194. $this->assertInstanceOf(get_class($this->historyExtension), $extensions[1]);
  195. }
  196. /**
  197. * @return array
  198. */
  199. protected function getConfig()
  200. {
  201. $config = array(
  202. 'extensions' => array(
  203. 'sonata_extension_publish' => array(
  204. 'admins' => array('sonata_post_admin'),
  205. 'implements' => array('Sonata\AdminBundle\Tests\DependencyInjection\Publishable'),
  206. ),
  207. 'sonata_extension_history' => array(
  208. 'excludes' => array('sonata_article_admin'),
  209. 'instanceof' => array('Sonata\AdminBundle\Tests\DependencyInjection\Post'),
  210. ),
  211. 'sonata_extension_order' => array(
  212. 'excludes' => array('sonata_post_admin'),
  213. 'extends' => array('Sonata\AdminBundle\Tests\DependencyInjection\Post'),
  214. 'implements' => array('Sonata\AdminBundle\Tests\DependencyInjection\Publishable'),
  215. ),
  216. )
  217. );
  218. return $config;
  219. }
  220. private function getContainer()
  221. {
  222. $container = new ContainerBuilder();
  223. $container->setParameter('kernel.bundles', array());
  224. // Add dependencies for SonataAdminBundle (these services will never get called so dummy classes will do)
  225. $container
  226. ->register('twig')
  227. ->setClass('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface');
  228. $container
  229. ->register('templating')
  230. ->setClass('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface');
  231. $container
  232. ->register('translator')
  233. ->setClass('Symfony\Bundle\FrameworkBundle\Translation\TranslatorInterface');
  234. $container
  235. ->register('validator.validator_factory')
  236. ->setClass('Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory');
  237. $container
  238. ->register('router')
  239. ->setClass('Symfony\Component\Routing\RouterInterface');
  240. // Add admin definition's
  241. $container
  242. ->register('sonata_post_admin')
  243. ->setClass('Sonata\AdminBundle\Tests\DependencyInjection\MockAdmin')
  244. ->setArguments(array('', 'Sonata\AdminBundle\Tests\DependencyInjection\Post', 'SonataAdminBundle:CRUD'))
  245. ->addTag('sonata.admin');
  246. $container
  247. ->register('sonata_news_admin')
  248. ->setClass('Sonata\AdminBundle\Tests\DependencyInjection\MockAdmin')
  249. ->setArguments(array('', 'Sonata\AdminBundle\Tests\DependencyInjection\News', 'SonataAdminBundle:CRUD'))
  250. ->addTag('sonata.admin');
  251. $container
  252. ->register('sonata_article_admin')
  253. ->setClass('Sonata\AdminBundle\Tests\DependencyInjection\MockAdmin')
  254. ->setArguments(array('', 'Sonata\AdminBundle\Tests\DependencyInjection\Article', 'SonataAdminBundle:CRUD'))
  255. ->addTag('sonata.admin');
  256. // Add admin extension definition's
  257. $container
  258. ->register('sonata_extension_publish')
  259. ->setClass(get_class($this->publishExtension));
  260. $container
  261. ->register('sonata_extension_history')
  262. ->setClass(get_class($this->historyExtension));
  263. $container
  264. ->register('sonata_extension_order')
  265. ->setClass(get_class($this->orderExtension));
  266. return $container;
  267. }
  268. }
  269. class MockAdmin extends Admin {}
  270. class Post {}
  271. interface Publishable {}
  272. class News extends Post {}
  273. class Article implements Publishable {}