Completed
Push — feature/modernize ( 3c43eb...622367 )
by Narcotic
06:44
created

ImportCommandTest::testRewrite()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 45
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 30
nc 1
nop 0
1
<?php
2
/**
3
 * check import command
4
 */
5
6
namespace Graviton\ImportExport\Tests\Command;
7
8
use Graviton\ImportExport\Command\ImportCommand;
9
use Symfony\Component\Console\Application;
10
use Symfony\Component\Console\Tester\CommandTester;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Finder\Finder;
13
use Symfony\Component\Yaml\Parser;
14
use Symfony\Component\VarDumper\Cloner\VarCloner;
15
use Symfony\Component\VarDumper\Dumper\CliDumper as Dumper;
16
use Webuni\FrontMatter\FrontMatter;
17
18
/**
19
 * @author   List of contributors <https://github.com/libgraviton/import-export/graphs/contributors>
20
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
21
 * @link     http://swisscom.ch
22
 */
23
class ImportCommandTest extends \PHPUnit_Framework_TestCase
24
{
25
    /**
26
     * String Http Client Class.
27
     */
28
    const CLIENT = 'Graviton\ImportExport\Service\HttpClient';
29
30
    /**
31
     * @dataProvider uploadFileProvider
32
     *
33
     * @param string $host import target host with protocol
34
     * @param string $file file to import
35
     * @param string $path resulting path from file
36
     *
37
     * @return void
38
     */
39
    public function testUploadFile($host, $file, $path)
40
    {
41
        $clientMock = $this->getMockBuilder(self::CLIENT)->getMock();
42
43
        $responseMock = $this->createMock('Psr\Http\Message\ResponseInterface');
44
45
        $responseMock
46
            ->method('getHeader')
47
            ->with('Link')
48
            ->willReturn(['<' . $host . $path . '>; rel="self"']);
49
50
        $clientMock
51
            ->method('request')
52
            ->will($this->returnValue($responseMock));
53
54
        $sut = new ImportCommand(
55
            $clientMock,
56
            new Finder(),
57
            new FrontMatter(),
58
            new Parser(),
59
            new VarCloner(),
60
            new Dumper()
61
        );
62
63
        $cmdTester = $this->getTester($sut, $file);
64
65
        $this->assertContains('Loading data from ' . $file, $cmdTester->getDisplay());
66
        $this->assertContains('Wrote <' . $host . $path . '>; rel="self"', $cmdTester->getDisplay());
67
        $this->assertEquals(0, $cmdTester->getStatusCode());
68
    }
69
70
    /**
71
     * @return array[]
72
     */
73
    public function uploadFileProvider()
74
    {
75
        return [
76
            'basic valid file' => [
77
                'http://localhost',
78
                __DIR__ . '/fixtures/set-01/test-2.json',
79
                '/core/app/test',
80
            ],
81
            'basic valid image file' => [
82
                'http://localhost',
83
                __DIR__ . '/fixtures/file',
84
                '/core/app/test',
85
            ],
86
        ];
87
    }
88
89
    /**
90
     * @dataProvider errorFileProvider
91
     *
92
     * @param string $host   import target host with protocol
93
     * @param string $file   file to import
94
     * @param array  $errors errors to check for (check valid case if none given)
95
     *
96
     * @return void
97
     */
98
    public function testErrorFile($host, $file, $errors = [])
99
    {
100
        $clientMock = $this->getMockBuilder(self::CLIENT)->getMock();
101
102
        $responseMock = $this->createMock('Psr\Http\Message\ResponseInterface');
103
104
        $responseMock
105
            ->method('getBody')
106
            ->willReturn(json_encode((object) ["message" => "invalid"]));
107
        $responseMock
108
            ->method('getHeader')
109
            ->with('Link')
110
            ->willReturn(['<' . $host . $file . '>; rel="self"']);
111
112
        $requestMock = $this->createMock('Psr\Http\Message\RequestInterface');
113
        $requestMock
114
            ->method('getUri')
115
            ->willReturn($host . '/core/app/test');
116
117
        $exceptionMock = $this->getMockBuilder('GuzzleHttp\Exception\RequestException')
118
            ->setConstructorArgs(['Client error: 400', $requestMock, $responseMock])
119
            ->getMock();
120
121
        $exceptionMock
122
            ->method('getRequest')
123
            ->willReturn($requestMock);
124
125
        $exceptionMock
126
            ->method('getResponse')
127
            ->willReturn($responseMock);
128
129
        $clientMock
130
            ->method('request')
131
            ->willThrowException($exceptionMock);
132
133
        $sut = new ImportCommand(
134
            $clientMock,
135
            new Finder(),
136
            new FrontMatter(),
137
            new Parser(),
138
            new VarCloner(),
139
            new Dumper()
140
        );
141
142
        $cmdTester = $this->getTester($sut, $file);
143
144
        $this->assertContains('Loading data from ' . $file, $cmdTester->getDisplay());
145
        foreach ($errors as $error) {
146
            $this->assertContains(
147
                $error,
148
                $cmdTester->getDisplay()
149
            );
150
        }
151
        $this->assertEquals(1, $cmdTester->getStatusCode());
152
    }
153
154
    /**
155
     * @return array[]
156
     */
157
    public function errorFileProvider()
158
    {
159
        return [
160
            'invalid file (server side)' => [
161
                'http://localhost',
162
                __DIR__ . '/fixtures/set-01/test.json',
163
                [
164
                    'Failed to write <http://localhost/core/app/test> from \'' .
165
                    __DIR__ . '/fixtures/set-01/test.json\' with message \'Client error: 400\'',
166
                    '"message": "invalid"',
167
                ],
168
            ],
169
            'missing target in file (user error)' => [
170
                'http://localhost',
171
                __DIR__ . '/fixtures/set-01/test-3.json',
172
                [
173
                    'Missing target in \'' . __DIR__ . '/fixtures/set-01/test-3.json\'',
174
                ],
175
            ]
176
        ];
177
    }
178
179
    /**
180
     * test rewriting of contents with --rewrite-host
181
     *
182
     * @return void
183
     */
184
    public function testRewrite()
185
    {
186
        $responseMock = $this->createMock('Psr\Http\Message\ResponseInterface');
187
188
        $responseMock
189
            ->method('getHeader')
190
            ->with('Link')
191
            ->willReturn(['<http://example.com/core/module/test>; rel="self"']);
192
193
        $clientMock = $this->getMockBuilder(self::CLIENT)->getMock();
194
195
        $clientMock
196
            ->method('request')
197
            ->with(
198
                $this->equalTo('PUT'),
199
                $this->equalTo('http://example.com/core/module/test'),
200
                $this->equalTo(
201
                    [
202
                        'json' => 'http://example.com/core/app/test',
203
                        'upload' => false
204
                    ]
205
                )
206
            )
207
            ->will($this->returnValue($responseMock));
208
209
        $sut = new ImportCommand(
210
            $clientMock,
211
            new Finder(),
212
            new FrontMatter(),
213
            new Parser(),
214
            new VarCloner(),
215
            new Dumper()
216
        );
217
218
        $cmdTester = $this->getTester(
219
            $sut,
220
            __DIR__ . '/fixtures/set-01/test-4.json',
221
            [
222
                'host' => 'http://example.com',
223
                '--rewrite-host' => 'http://localhost'
224
            ]
225
        );
226
        $this->assertContains('Wrote <http://example.com/core/module/test>; rel="self"', $cmdTester->getDisplay());
227
        $this->assertEquals(0, $cmdTester->getStatusCode());
228
    }
229
230
    /**
231
     * @param ImportCommand $sut  command under test
232
     * @param string        $file file to load
233
     * @param array         $args additional arguments
234
     *
235
     * @return CommandTester
236
     */
237
    private function getTester(ImportCommand $sut, $file, array $args = [])
238
    {
239
        $app = new Application();
240
        $app->add($sut);
241
242
        $cmd = $app->find('g:i');
243
        $cmdTester = new CommandTester($cmd);
244
        $cmdTester->execute(
245
            array_merge(
246
                [
247
                    'command' => $cmd->getName(),
248
                    'host' => 'http://localhost',
249
                    'file' => [
250
                        $file
251
                    ],
252
                ],
253
                $args
254
            ),
255
            [
256
                'decorated' => true,
257
                'verbosity' => OutputInterface::VERBOSITY_VERBOSE,
258
            ]
259
        );
260
        return $cmdTester;
261
    }
262
}
263