Passed
Pull Request — master (#442)
by Alejandro
16:19 queued 08:26
created

CreateDatabaseCommandTest   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 5
eloc 83
c 3
b 0
f 0
dl 0
loc 133
rs 10

5 Methods

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