Completed
Pull Request — develop (#19)
by
unknown
05:29 queued 02:09
created

ImportCommandTest::uploadImageFileProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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