Completed
Push — master ( ac98ee...01982b )
by ANTHONIUS
02:45
created

SelfUpdateCommandTest   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 7
dl 0
loc 151
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the dotfiles project.
7
 *
8
 *     (c) Anthonius Munthi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Dotfiles\Core\Tests\Command;
15
16
use Dotfiles\Core\Application;
17
use Dotfiles\Core\Command\SelfUpdateCommand;
18
use Dotfiles\Core\Config\Config;
19
use Dotfiles\Core\Exceptions\InstallFailedException;
20
use Dotfiles\Core\Tests\BaseTestCase;
21
use Dotfiles\Core\Util\Downloader;
22
use Dotfiles\Core\Util\Filesystem;
23
use Dotfiles\Core\Util\Toolkit;
24
use PHPUnit\Framework\MockObject\MockObject;
25
use Symfony\Component\Console\Helper\ProgressBar;
26
use Symfony\Component\Console\Input\InputInterface;
27
use Symfony\Component\Console\Output\OutputInterface;
28
29
class SelfUpdateCommandTest extends BaseTestCase
30
{
31
    /**
32
     * @var MockObject
33
     */
34
    private $config;
35
36
    /**
37
     * @var MockObject
38
     */
39
    private $downloader;
40
41
    /**
42
     * @var InputInterface
43
     */
44
    private $input;
45
46
    /**
47
     * @var OutputInterface
48
     */
49
    private $output;
50
51
    /**
52
     * @var ProgressBar
53
     */
54
    private $progressBar;
55
56
    /**
57
     * @var string
58
     */
59
    private $tempDir;
60
61
    public function setUp(): void/* The :void return type declaration that should be here would cause a BC issue */
62
    {
63
        $this->config = $this->createMock(Config::class);
64
        $this->downloader = $this->createMock(Downloader::class);
65
        $this->tempDir = sys_get_temp_dir().'/dotfiles';
66
        $this->output = $this->createMock(OutputInterface::class);
67
        $this->input = $this->createMock(InputInterface::class);
68
        $this->progressBar = new ProgressBar($this->output);
69
        static::cleanupTempDir();
70
    }
71
72
    public function createFakeVersionFile($url, $target): void
73
    {
74
        if (false !== strpos($url, 'dotfiles.phar.json')) {
75
            $origin = __DIR__.'/fixtures/dotfiles.phar.json';
76
        } else {
77
            $origin = __DIR__.'/fixtures/dotfiles.phar';
78
        }
79
        $fs = new Filesystem();
80
        $fs->copy($origin, $target);
81
82
        return;
83
    }
84
85
    public function testExecute(): void
86
    {
87
        $tempDir = $this->tempDir;
88
        $versionFile = $tempDir.'/temp/update/dotfiles.phar.json';
89
        $pharFile = $tempDir.'/temp/update/test/dotfiles.phar';
90
91
        Toolkit::ensureFileDir($versionFile);
92
93
        $this->downloader->expects($this->exactly(2))
94
            ->method('run')
95
            ->withConsecutive(
96
                array(SelfUpdateCommand::BASE_URL.'/dotfiles.phar.json', $versionFile),
97
                array(SelfUpdateCommand::BASE_URL.'/dotfiles.phar', $pharFile)
98
            )
99
            ->will(
100
                $this->returnCallback(array($this, 'createFakeVersionFile'))
101
            )
102
        ;
103
        $command = $this->getSUT();
104
        $command->execute($this->input, $this->output);
105
    }
106
107
    public function testExecuteOnLatestVersionPhar(): void
108
    {
109
        $version = Application::VERSION;
110
        $versionFile = <<<EOF
111
{
112
    "version": "{$version}",
113
    "branch": "1.0-dev",
114
    "date": "2018-04-08 06:50:24",
115
    "sha256": "51ccbace494495e667c9b77bb628bc0ddae590f268524bf644419745e86a07aa  dotfiles.pha"
116
}
117
EOF;
118
119
        $this->downloader->expects($this->once())
120
            ->method('run')
121
            ->will(
122
                $this->returnCallback(
123
                    function ($url, $target) use ($versionFile): void {
124
                        file_put_contents($target, $versionFile, LOCK_EX);
125
                    }
126
                )
127
            )
128
        ;
129
        $this->output->expects($this->exactly(2))
130
            ->method('writeln')
131
            ->withConsecutive(
132
                array($this->stringContains('Start checking new version')),
133
                array($this->stringContains('You already have latest'))
134
            )
135
        ;
136
        $command = $this->getSUT();
137
        $command->execute($this->input, $this->output);
138
    }
139
140
    public function testExecuteThrowsOnEmptyVersionFile(): void
141
    {
142
        $this->downloader->expects($this->once())
143
            ->method('run')
144
            ->will(
145
                $this->returnCallback(
146
                    function ($url, $target): void {
147
                        touch($target);
148
                    }
149
                )
150
            )
151
        ;
152
153
        $this->expectException(InstallFailedException::class);
154
        $this->expectExceptionMessage('Can not parse dotfiles.phar.json file');
155
        $command = $this->getSUT();
156
        $command->execute($this->input, $this->output);
157
    }
158
159
    private function getSUT()
160
    {
161
        $tempDir = $this->tempDir;
162
163
        $this->config->expects($this->any())
164
            ->method('get')
165
            ->willReturnMap(array(
166
                array('dotfiles.temp_dir', $tempDir.'/temp'),
167
                array('dotfiles.cache_dir', $tempDir.'/cache'),
168
                array('dotfiles.dry_run', false),
169
            ))
170
        ;
171
        $this->downloader->expects($this->any())
172
            ->method('getProgressBar')
173
            ->willReturn($this->progressBar)
174
        ;
175
176
        return new SelfUpdateCommand(
177
            null,
178
            $this->downloader,
179
            $this->config
180
        );
181
    }
182
}
183