IntegrationTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\Bundle\FixturesBundle\Tests;
  4. use Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand;
  5. use Doctrine\Bundle\FixturesBundle\DependencyInjection\CompilerPass\FixturesCompilerPass;
  6. use Doctrine\Bundle\FixturesBundle\DependencyInjection\CompilerPass\PurgerFactoryCompilerPass;
  7. use Doctrine\Bundle\FixturesBundle\Purger\PurgerFactory;
  8. use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\DependentOnRequiredConstructorArgsFixtures;
  9. use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\OtherFixtures;
  10. use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\RequiredConstructorArgsFixtures;
  11. use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDependenciesFixtures;
  12. use Doctrine\Common\DataFixtures\Loader;
  13. use Doctrine\Common\DataFixtures\Purger\ORMPurger;
  14. use Doctrine\Common\EventManager;
  15. use Doctrine\DBAL\Connection;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Doctrine\Persistence\ManagerRegistry;
  18. use LogicException;
  19. use PHPUnit\Framework\TestCase;
  20. use RuntimeException;
  21. use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
  22. use Symfony\Component\Console\Tester\CommandTester;
  23. use Symfony\Component\DependencyInjection\Alias;
  24. use Symfony\Component\DependencyInjection\ContainerBuilder;
  25. use Symfony\Component\DependencyInjection\Definition;
  26. use function array_map;
  27. use function get_class;
  28. use function method_exists;
  29. class IntegrationTest extends TestCase
  30. {
  31. public function testFixturesLoader() : void
  32. {
  33. $kernel = new IntegrationTestKernel('dev', true);
  34. $kernel->addServices(static function (ContainerBuilder $c) : void {
  35. $c->autowire(OtherFixtures::class)
  36. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  37. $c->autowire(WithDependenciesFixtures::class)
  38. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  39. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  40. });
  41. $kernel->boot();
  42. $container = $kernel->getContainer();
  43. /** @var ContainerAwareLoader $loader */
  44. $loader = $container->get('test.doctrine.fixtures.loader');
  45. $actualFixtures = $loader->getFixtures();
  46. $this->assertCount(2, $actualFixtures);
  47. $actualFixtureClasses = array_map(static function ($fixture) {
  48. return get_class($fixture);
  49. }, $actualFixtures);
  50. $this->assertSame([
  51. OtherFixtures::class,
  52. WithDependenciesFixtures::class,
  53. ], $actualFixtureClasses);
  54. $this->assertInstanceOf(WithDependenciesFixtures::class, $actualFixtures[1]);
  55. }
  56. public function testFixturesLoaderWhenFixtureHasDepdencenyThatIsNotYetLoaded() : void
  57. {
  58. // See https://github.com/doctrine/DoctrineFixturesBundle/issues/215
  59. $kernel = new IntegrationTestKernel('dev', true);
  60. $kernel->addServices(static function (ContainerBuilder $c) : void {
  61. $c->autowire(WithDependenciesFixtures::class)
  62. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  63. $c->autowire(OtherFixtures::class)
  64. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  65. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  66. });
  67. $kernel->boot();
  68. $container = $kernel->getContainer();
  69. /** @var ContainerAwareLoader $loader */
  70. $loader = $container->get('test.doctrine.fixtures.loader');
  71. $actualFixtures = $loader->getFixtures();
  72. $this->assertCount(2, $actualFixtures);
  73. $actualFixtureClasses = array_map(static function ($fixture) {
  74. return get_class($fixture);
  75. }, $actualFixtures);
  76. $this->assertSame([
  77. OtherFixtures::class,
  78. WithDependenciesFixtures::class,
  79. ], $actualFixtureClasses);
  80. $this->assertInstanceOf(WithDependenciesFixtures::class, $actualFixtures[1]);
  81. }
  82. public function testExceptionWithDependenciesWithRequiredArguments() : void
  83. {
  84. // see https://github.com/doctrine/data-fixtures/pull/274
  85. // When that is merged, this test will only run when using
  86. // an older version of that library.
  87. if (method_exists(Loader::class, 'createFixture')) {
  88. $this->markTestSkipped();
  89. }
  90. $kernel = new IntegrationTestKernel('dev', true);
  91. $kernel->addServices(static function (ContainerBuilder $c) : void {
  92. $c->autowire(DependentOnRequiredConstructorArgsFixtures::class)
  93. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  94. $c->autowire(RequiredConstructorArgsFixtures::class)
  95. ->setArgument(0, 'foo')
  96. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  97. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  98. });
  99. $kernel->boot();
  100. $container = $kernel->getContainer();
  101. $this->expectException(LogicException::class);
  102. $this->expectExceptionMessage('The getDependencies() method returned a class (Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\RequiredConstructorArgsFixtures) that has required constructor arguments. Upgrade to "doctrine/data-fixtures" version 1.3 or higher to support this.');
  103. /** @var ContainerAwareLoader $loader */
  104. $loader = $container->get('test.doctrine.fixtures.loader');
  105. $loader->getFixtures();
  106. }
  107. public function testExceptionIfDependentFixtureNotWired() : void
  108. {
  109. // only runs on newer versions of doctrine/data-fixtures
  110. if (! method_exists(Loader::class, 'createFixture')) {
  111. $this->markTestSkipped();
  112. }
  113. $kernel = new IntegrationTestKernel('dev', true);
  114. $kernel->addServices(static function (ContainerBuilder $c) : void {
  115. $c->autowire(DependentOnRequiredConstructorArgsFixtures::class)
  116. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  117. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  118. });
  119. $kernel->boot();
  120. $container = $kernel->getContainer();
  121. $this->expectException(LogicException::class);
  122. $this->expectExceptionMessage('The "Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\RequiredConstructorArgsFixtures" fixture class is trying to be loaded, but is not available. Make sure this class is defined as a service and tagged with "doctrine.fixture.orm".');
  123. /** @var ContainerAwareLoader $loader */
  124. $loader = $container->get('test.doctrine.fixtures.loader');
  125. $loader->getFixtures();
  126. }
  127. public function testFixturesLoaderWithGroupsOptionViaInterface() : void
  128. {
  129. $kernel = new IntegrationTestKernel('dev', true);
  130. $kernel->addServices(static function (ContainerBuilder $c) : void {
  131. // has a "staging" group via the getGroups() method
  132. $c->autowire(OtherFixtures::class)
  133. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  134. // no getGroups() method
  135. $c->autowire(WithDependenciesFixtures::class)
  136. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  137. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  138. });
  139. $kernel->boot();
  140. $container = $kernel->getContainer();
  141. /** @var ContainerAwareLoader $loader */
  142. $loader = $container->get('test.doctrine.fixtures.loader');
  143. $actualFixtures = $loader->getFixtures(['staging']);
  144. $this->assertCount(1, $actualFixtures);
  145. $actualFixtureClasses = array_map(static function ($fixture) {
  146. return get_class($fixture);
  147. }, $actualFixtures);
  148. $this->assertSame([
  149. OtherFixtures::class,
  150. ], $actualFixtureClasses);
  151. $this->assertInstanceOf(OtherFixtures::class, $actualFixtures[0]);
  152. }
  153. public function testFixturesLoaderWithGroupsOptionViaTag() : void
  154. {
  155. $kernel = new IntegrationTestKernel('dev', true);
  156. $kernel->addServices(static function (ContainerBuilder $c) : void {
  157. // has a "staging" group via the getGroups() method
  158. $c->autowire(OtherFixtures::class)
  159. ->addTag(FixturesCompilerPass::FIXTURE_TAG, ['group' => 'group1'])
  160. ->addTag(FixturesCompilerPass::FIXTURE_TAG, ['group' => 'group2']);
  161. // no getGroups() method
  162. $c->autowire(WithDependenciesFixtures::class)
  163. ->addTag(FixturesCompilerPass::FIXTURE_TAG, ['group' => 'group2']);
  164. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  165. });
  166. $kernel->boot();
  167. $container = $kernel->getContainer();
  168. /** @var ContainerAwareLoader $loader */
  169. $loader = $container->get('test.doctrine.fixtures.loader');
  170. $this->assertCount(1, $loader->getFixtures(['staging']));
  171. $this->assertCount(1, $loader->getFixtures(['group1']));
  172. $this->assertCount(2, $loader->getFixtures(['group2']));
  173. $this->assertCount(0, $loader->getFixtures(['group3']));
  174. }
  175. public function testLoadFixturesViaGroupWithMissingDependency() : void
  176. {
  177. $kernel = new IntegrationTestKernel('dev', true);
  178. $kernel->addServices(static function (ContainerBuilder $c) : void {
  179. // has a "staging" group via the getGroups() method
  180. $c->autowire(OtherFixtures::class)
  181. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  182. // no getGroups() method
  183. $c->autowire(WithDependenciesFixtures::class)
  184. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  185. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  186. });
  187. $kernel->boot();
  188. $container = $kernel->getContainer();
  189. /** @var ContainerAwareLoader $loader */
  190. $loader = $container->get('test.doctrine.fixtures.loader');
  191. $this->expectException(RuntimeException::class);
  192. $this->expectExceptionMessage('Fixture "Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\OtherFixtures" was declared as a dependency for fixture "Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDependenciesFixtures", but it was not included in any of the loaded fixture groups.');
  193. $loader->getFixtures(['missingDependencyGroup']);
  194. }
  195. public function testLoadFixturesViaGroupWithFulfilledDependency() : void
  196. {
  197. $kernel = new IntegrationTestKernel('dev', true);
  198. $kernel->addServices(static function (ContainerBuilder $c) : void {
  199. // has a "staging" group via the getGroups() method
  200. $c->autowire(OtherFixtures::class)
  201. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  202. // no getGroups() method
  203. $c->autowire(WithDependenciesFixtures::class)
  204. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  205. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  206. });
  207. $kernel->boot();
  208. $container = $kernel->getContainer();
  209. /** @var ContainerAwareLoader $loader */
  210. $loader = $container->get('test.doctrine.fixtures.loader');
  211. $actualFixtures = $loader->getFixtures(['fulfilledDependencyGroup']);
  212. $this->assertCount(2, $actualFixtures);
  213. $actualFixtureClasses = array_map(static function ($fixture) {
  214. return get_class($fixture);
  215. }, $actualFixtures);
  216. $this->assertSame([
  217. OtherFixtures::class,
  218. WithDependenciesFixtures::class,
  219. ], $actualFixtureClasses);
  220. }
  221. public function testLoadFixturesByShortName() : void
  222. {
  223. $kernel = new IntegrationTestKernel('dev', true);
  224. $kernel->addServices(static function (ContainerBuilder $c) : void {
  225. // has a "staging" group via the getGroups() method
  226. $c->autowire(OtherFixtures::class)
  227. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  228. // no getGroups() method
  229. $c->autowire(WithDependenciesFixtures::class)
  230. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  231. $c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
  232. });
  233. $kernel->boot();
  234. $container = $kernel->getContainer();
  235. /** @var ContainerAwareLoader $loader */
  236. $loader = $container->get('test.doctrine.fixtures.loader');
  237. $actualFixtures = $loader->getFixtures(['OtherFixtures']);
  238. $this->assertCount(1, $actualFixtures);
  239. $actualFixtureClasses = array_map(static function ($fixture) {
  240. return get_class($fixture);
  241. }, $actualFixtures);
  242. $this->assertSame([
  243. OtherFixtures::class,
  244. ], $actualFixtureClasses);
  245. }
  246. public function testRunCommandWithDefaultPurger() : void
  247. {
  248. $kernel = new IntegrationTestKernel('dev', true);
  249. $kernel->addServices(static function (ContainerBuilder $c) : void {
  250. // has a "staging" group via the getGroups() method
  251. $c->autowire(OtherFixtures::class)
  252. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  253. // no getGroups() method
  254. $c->autowire(WithDependenciesFixtures::class)
  255. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  256. $c->getDefinition('doctrine')
  257. ->setPublic(true)
  258. ->setSynthetic(true);
  259. $c->setAlias('test.doctrine.fixtures.purger.orm_purger_factory', new Alias('doctrine.fixtures.purger.orm_purger_factory', true));
  260. $c->setAlias('test.doctrine.fixtures_load_command', new Alias('doctrine.fixtures_load_command', true));
  261. });
  262. $kernel->boot();
  263. $container = $kernel->getContainer();
  264. $em = $this->createConfiguredMock(EntityManagerInterface::class, ['getConnection' => $this->createMock(Connection::class), 'getEventManager' => $this->createMock(EventManager::class)]);
  265. $registry = $this->createMock(ManagerRegistry::class);
  266. $registry
  267. ->expects(self::once())
  268. ->method('getManager')
  269. ->with(null)
  270. ->willReturn($em);
  271. $container->set('doctrine', $registry);
  272. $purgerFactory = $this->createMock(PurgerFactory::class);
  273. $purger = $this->createMock(ORMPurger::class);
  274. $purgerFactory
  275. ->expects(self::once())
  276. ->method('createForEntityManager')
  277. ->with(null, $em, [])
  278. ->willReturn($purger);
  279. $container->set('test.doctrine.fixtures.purger.orm_purger_factory', $purgerFactory);
  280. /** @var LoadDataFixturesDoctrineCommand $command */
  281. $command = $container->get('test.doctrine.fixtures_load_command');
  282. $tester = new CommandTester($command);
  283. $tester->execute([], ['interactive' => false]);
  284. }
  285. public function testRunCommandWithPurgeExclusions() : void
  286. {
  287. $kernel = new IntegrationTestKernel('dev', true);
  288. $kernel->addServices(static function (ContainerBuilder $c) : void {
  289. // has a "staging" group via the getGroups() method
  290. $c->autowire(OtherFixtures::class)
  291. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  292. // no getGroups() method
  293. $c->autowire(WithDependenciesFixtures::class)
  294. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  295. $c->getDefinition('doctrine')
  296. ->setPublic(true)
  297. ->setSynthetic(true);
  298. $c->setAlias('test.doctrine.fixtures.purger.orm_purger_factory', new Alias('doctrine.fixtures.purger.orm_purger_factory', true));
  299. $c->setAlias('test.doctrine.fixtures_load_command', new Alias('doctrine.fixtures_load_command', true));
  300. });
  301. $kernel->boot();
  302. $container = $kernel->getContainer();
  303. $em = $this->createConfiguredMock(EntityManagerInterface::class, ['getConnection' => $this->createMock(Connection::class), 'getEventManager' => $this->createMock(EventManager::class)]);
  304. $registry = $this->createMock(ManagerRegistry::class);
  305. $registry
  306. ->expects(self::once())
  307. ->method('getManager')
  308. ->with(null)
  309. ->willReturn($em);
  310. $container->set('doctrine', $registry);
  311. $purgerFactory = $this->createMock(PurgerFactory::class);
  312. $purger = $this->createMock(ORMPurger::class);
  313. $purgerFactory
  314. ->expects(self::once())
  315. ->method('createForEntityManager')
  316. ->with(null, $em, ['excluded_table'])
  317. ->willReturn($purger);
  318. $container->set('test.doctrine.fixtures.purger.orm_purger_factory', $purgerFactory);
  319. /** @var LoadDataFixturesDoctrineCommand $command */
  320. $command = $container->get('test.doctrine.fixtures_load_command');
  321. $tester = new CommandTester($command);
  322. $tester->execute(['--purge-exclusions' => ['excluded_table']], ['interactive' => false]);
  323. }
  324. public function testRunCommandWithCustomPurgerAndCustomEntityManager() : void
  325. {
  326. $kernel = new IntegrationTestKernel('dev', true);
  327. $kernel->addServices(static function (ContainerBuilder $c) : void {
  328. // has a "staging" group via the getGroups() method
  329. $c->autowire(OtherFixtures::class)
  330. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  331. // no getGroups() method
  332. $c->autowire(WithDependenciesFixtures::class)
  333. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  334. $c->getDefinition('doctrine')
  335. ->setPublic(true)
  336. ->setSynthetic(true);
  337. $c->setDefinition('test.doctrine.fixtures.purger.test_factory', (new Definition())
  338. ->setPublic(true)
  339. ->setSynthetic(true)
  340. ->addTag(PurgerFactoryCompilerPass::PURGER_FACTORY_TAG, ['alias' => 'test']));
  341. $c->setAlias('test.doctrine.fixtures_load_command', new Alias('doctrine.fixtures_load_command', true));
  342. });
  343. $kernel->boot();
  344. $container = $kernel->getContainer();
  345. $em = $this->createConfiguredMock(EntityManagerInterface::class, ['getConnection' => $this->createMock(Connection::class), 'getEventManager' => $this->createMock(EventManager::class)]);
  346. $registry = $this->createMock(ManagerRegistry::class);
  347. $registry
  348. ->expects(self::once())
  349. ->method('getManager')
  350. ->with('alternative')
  351. ->willReturn($em);
  352. $container->set('doctrine', $registry);
  353. $purgerFactory = $this->createMock(PurgerFactory::class);
  354. $purger = $this->createMock(ORMPurger::class);
  355. $purgerFactory
  356. ->expects(self::once())
  357. ->method('createForEntityManager')
  358. ->with('alternative', $em, [])
  359. ->willReturn($purger);
  360. $container->set('test.doctrine.fixtures.purger.test_factory', $purgerFactory);
  361. /** @var LoadDataFixturesDoctrineCommand $command */
  362. $command = $container->get('test.doctrine.fixtures_load_command');
  363. $tester = new CommandTester($command);
  364. $tester->execute(['--purger' => 'test', '--em' => 'alternative'], ['interactive' => false]);
  365. }
  366. public function testRunCommandWithPurgeMode() : void
  367. {
  368. $kernel = new IntegrationTestKernel('dev', true);
  369. $kernel->addServices(static function (ContainerBuilder $c) : void {
  370. // has a "staging" group via the getGroups() method
  371. $c->autowire(OtherFixtures::class)
  372. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  373. // no getGroups() method
  374. $c->autowire(WithDependenciesFixtures::class)
  375. ->addTag(FixturesCompilerPass::FIXTURE_TAG);
  376. $c->getDefinition('doctrine')
  377. ->setPublic(true)
  378. ->setSynthetic(true);
  379. $c->setAlias('test.doctrine.fixtures.purger.orm_purger_factory', new Alias('doctrine.fixtures.purger.orm_purger_factory', true));
  380. $c->setAlias('test.doctrine.fixtures_load_command', new Alias('doctrine.fixtures_load_command', true));
  381. });
  382. $kernel->boot();
  383. $container = $kernel->getContainer();
  384. $em = $this->createConfiguredMock(EntityManagerInterface::class, ['getConnection' => $this->createMock(Connection::class), 'getEventManager' => $this->createMock(EventManager::class)]);
  385. $registry = $this->createMock(ManagerRegistry::class);
  386. $registry
  387. ->expects(self::once())
  388. ->method('getManager')
  389. ->with(null)
  390. ->willReturn($em);
  391. $container->set('doctrine', $registry);
  392. $purgerFactory = $this->createMock(PurgerFactory::class);
  393. $purger = $this->createMock(ORMPurger::class);
  394. $purgerFactory
  395. ->expects(self::once())
  396. ->method('createForEntityManager')
  397. ->with(null, $em, [], true)
  398. ->willReturn($purger);
  399. $container->set('test.doctrine.fixtures.purger.orm_purger_factory', $purgerFactory);
  400. /** @var LoadDataFixturesDoctrineCommand $command */
  401. $command = $container->get('test.doctrine.fixtures_load_command');
  402. $tester = new CommandTester($command);
  403. $tester->execute(['--purge-with-truncate' => true], ['interactive' => false]);
  404. }
  405. }