Completed
Push — feature/EVO-3237-send-file-par... ( ff951d...f7050e )
by Lucas
03:01
created

ImportCommandTest::uploadImageFileProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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