CreateDatabaseCommandTest.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. declare(strict_types=1);
  3. namespace ShlinkioTest\Shlink\CLI\Command\Db;
  4. use Doctrine\DBAL\Connection;
  5. use Doctrine\DBAL\Platforms\AbstractPlatform;
  6. use Doctrine\DBAL\Schema\AbstractSchemaManager;
  7. use PHPUnit\Framework\TestCase;
  8. use Prophecy\Argument;
  9. use Prophecy\PhpUnit\ProphecyTrait;
  10. use Prophecy\Prophecy\ObjectProphecy;
  11. use Shlinkio\Shlink\CLI\Command\Db\CreateDatabaseCommand;
  12. use Shlinkio\Shlink\CLI\Util\ProcessRunnerInterface;
  13. use Symfony\Component\Console\Application;
  14. use Symfony\Component\Console\Output\OutputInterface;
  15. use Symfony\Component\Console\Tester\CommandTester;
  16. use Symfony\Component\Lock\LockFactory;
  17. use Symfony\Component\Lock\LockInterface;
  18. use Symfony\Component\Process\PhpExecutableFinder;
  19. class CreateDatabaseCommandTest extends TestCase
  20. {
  21. use ProphecyTrait;
  22. private CommandTester $commandTester;
  23. private ObjectProphecy $processHelper;
  24. private ObjectProphecy $regularConn;
  25. private ObjectProphecy $schemaManager;
  26. private ObjectProphecy $databasePlatform;
  27. public function setUp(): void
  28. {
  29. $locker = $this->prophesize(LockFactory::class);
  30. $lock = $this->prophesize(LockInterface::class);
  31. $lock->acquire(Argument::any())->willReturn(true);
  32. $lock->release()->will(function (): void {
  33. });
  34. $locker->createLock(Argument::cetera())->willReturn($lock->reveal());
  35. $phpExecutableFinder = $this->prophesize(PhpExecutableFinder::class);
  36. $phpExecutableFinder->find(false)->willReturn('/usr/local/bin/php');
  37. $this->processHelper = $this->prophesize(ProcessRunnerInterface::class);
  38. $this->schemaManager = $this->prophesize(AbstractSchemaManager::class);
  39. $this->databasePlatform = $this->prophesize(AbstractPlatform::class);
  40. $this->regularConn = $this->prophesize(Connection::class);
  41. $this->regularConn->getSchemaManager()->willReturn($this->schemaManager->reveal());
  42. $this->regularConn->getDatabasePlatform()->willReturn($this->databasePlatform->reveal());
  43. $noDbNameConn = $this->prophesize(Connection::class);
  44. $noDbNameConn->getSchemaManager()->willReturn($this->schemaManager->reveal());
  45. $command = new CreateDatabaseCommand(
  46. $locker->reveal(),
  47. $this->processHelper->reveal(),
  48. $phpExecutableFinder->reveal(),
  49. $this->regularConn->reveal(),
  50. $noDbNameConn->reveal(),
  51. );
  52. $app = new Application();
  53. $app->add($command);
  54. $this->commandTester = new CommandTester($command);
  55. }
  56. /** @test */
  57. public function successMessageIsPrintedIfDatabaseAlreadyExists(): void
  58. {
  59. $shlinkDatabase = 'shlink_database';
  60. $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
  61. $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', $shlinkDatabase, 'bar']);
  62. $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
  63. });
  64. $listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']);
  65. $this->commandTester->execute([]);
  66. $output = $this->commandTester->getDisplay();
  67. self::assertStringContainsString('Database already exists. Run "db:migrate" command', $output);
  68. $getDatabase->shouldHaveBeenCalledOnce();
  69. $listDatabases->shouldHaveBeenCalledOnce();
  70. $createDatabase->shouldNotHaveBeenCalled();
  71. $listTables->shouldHaveBeenCalledOnce();
  72. }
  73. /** @test */
  74. public function databaseIsCreatedIfItDoesNotExist(): void
  75. {
  76. $shlinkDatabase = 'shlink_database';
  77. $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
  78. $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', 'bar']);
  79. $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
  80. });
  81. $listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']);
  82. $this->commandTester->execute([]);
  83. $getDatabase->shouldHaveBeenCalledOnce();
  84. $listDatabases->shouldHaveBeenCalledOnce();
  85. $createDatabase->shouldHaveBeenCalledOnce();
  86. $listTables->shouldHaveBeenCalledOnce();
  87. }
  88. /** @test */
  89. public function tablesAreCreatedIfDatabaseIsEmpty(): void
  90. {
  91. $shlinkDatabase = 'shlink_database';
  92. $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
  93. $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', $shlinkDatabase, 'bar']);
  94. $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
  95. });
  96. $listTables = $this->schemaManager->listTableNames()->willReturn([]);
  97. $runCommand = $this->processHelper->run(Argument::type(OutputInterface::class), [
  98. '/usr/local/bin/php',
  99. CreateDatabaseCommand::DOCTRINE_SCRIPT,
  100. CreateDatabaseCommand::DOCTRINE_CREATE_SCHEMA_COMMAND,
  101. '--no-interaction',
  102. ]);
  103. $this->commandTester->execute([]);
  104. $output = $this->commandTester->getDisplay();
  105. self::assertStringContainsString('Creating database tables...', $output);
  106. self::assertStringContainsString('Database properly created!', $output);
  107. $getDatabase->shouldHaveBeenCalledOnce();
  108. $listDatabases->shouldHaveBeenCalledOnce();
  109. $createDatabase->shouldNotHaveBeenCalled();
  110. $listTables->shouldHaveBeenCalledOnce();
  111. $runCommand->shouldHaveBeenCalledOnce();
  112. }
  113. /** @test */
  114. public function databaseCheckIsSkippedForSqlite(): void
  115. {
  116. $this->databasePlatform->getName()->willReturn('sqlite');
  117. $shlinkDatabase = 'shlink_database';
  118. $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
  119. $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', 'bar']);
  120. $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
  121. });
  122. $listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']);
  123. $this->commandTester->execute([]);
  124. $getDatabase->shouldNotHaveBeenCalled();
  125. $listDatabases->shouldNotHaveBeenCalled();
  126. $createDatabase->shouldNotHaveBeenCalled();
  127. $listTables->shouldHaveBeenCalledOnce();
  128. }
  129. }