Completed
Push — develop ( 9af4bd...daa113 )
by
unknown
7s
created

ImportCommandTest::testUploadFile()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 41
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

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