Completed
Push — master ( a4e6c9...41bf94 )
by
unknown
02:37
created

ImportCommandTest   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 269
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 7
c 4
b 0
f 0
lcom 1
cbo 11
dl 0
loc 269
rs 10

6 Methods

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