Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.33% covered (warning)
64.33%
202 / 314
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
phpbb_attachment_upload_test
64.33% covered (warning)
64.33%
202 / 314
71.43% covered (warning)
71.43%
5 / 7
16.49
0.00% covered (danger)
0.00%
0 / 1
 getDataSet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUp
100.00% covered (success)
100.00%
77 / 77
100.00% covered (success)
100.00%
1 / 1
1
 data_upload
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
2
 test_upload
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 test_init_error
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
1 / 1
1
 data_image_upload
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 1
2
 test_image_upload
100.00% covered (success)
100.00%
74 / 74
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14require_once(__DIR__ . '/../../phpBB/includes/functions_posting.php');
15
16class phpbb_attachment_upload_test extends \phpbb_database_test_case
17{
18    /** @var \phpbb\auth\auth */
19    protected $auth;
20
21    /** @var \phpbb\cache\service */
22    protected $cache;
23
24    /** @var \phpbb\config\config */
25    protected $config;
26
27    /** @var \phpbb\files\upload */
28    protected $files_upload;
29
30    /** @var \phpbb\language\language */
31    protected $language;
32
33    /** @var \phpbb\mimetype\guesser */
34    protected $mimetype_guesser;
35
36    /** @var \phpbb\event\dispatcher */
37    protected $phpbb_dispatcher;
38
39    /** @var \phpbb\plupload\plupload */
40    protected $plupload;
41
42    /** @var \phpbb\storage\storage */
43    protected $storage;
44
45    /** @var \phpbb\user */
46    protected $user;
47
48    /** @var \phpbb\db\driver\driver_interface */
49    protected $db;
50
51    /** @var \phpbb\attachment\upload */
52    protected $upload;
53
54    /** @var \phpbb\filesystem\filesystem */
55    private $filesystem;
56
57    /** @var \phpbb\filesystem\temp */
58    protected $temp;
59
60    /** @var \Symfony\Component\DependencyInjection\ContainerInterface */
61    protected $container;
62
63    /** @var \phpbb\files\factory */
64    protected $factory;
65
66    /** @var \bantu\IniGetWrapper\IniGetWrapper */
67    protected $php_ini;
68
69    /** @var \phpbb\request\request */
70    protected $request;
71
72    /** @var string */
73    protected $phpbb_root_path;
74
75    public function getDataSet()
76    {
77        return $this->createXMLDataSet(__DIR__ . '/fixtures/resync.xml');
78    }
79
80    protected function setUp(): void
81    {
82        global $config, $phpbb_root_path, $phpEx;
83
84        parent::setUp();
85
86        $this->auth = new \phpbb\auth\auth();
87        $this->config = new \phpbb\config\config(array(
88            'img_create_thumbnail'    => true,
89        ));
90        $config = $this->config;
91        $this->phpbb_root_path = $phpbb_root_path;
92        $this->db = $this->new_dbal();
93        $this->phpbb_dispatcher = new phpbb_mock_event_dispatcher();
94        $this->cache = new \phpbb\cache\service(new \phpbb\cache\driver\dummy(), $this->config, $this->db, $this->phpbb_dispatcher, $phpbb_root_path, $phpEx);
95        $this->request = $this->createMock('\phpbb\request\request');
96
97        $this->filesystem = new \phpbb\filesystem\filesystem();
98        $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
99        $this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
100        $guessers = array(
101            new \Symfony\Component\Mime\FileinfoMimeTypeGuesser(),
102            new \Symfony\Component\Mime\FileBinaryMimeTypeGuesser(),
103            new \phpbb\mimetype\content_guesser(),
104            new \phpbb\mimetype\extension_guesser(),
105        );
106        $guessers[2]->set_priority(-2);
107        $guessers[3]->set_priority(-2);
108        $this->mimetype_guesser = new \phpbb\mimetype\guesser($guessers);
109        $this->plupload = new \phpbb\plupload\plupload($phpbb_root_path, $this->config, $this->request, new \phpbb\user($this->language, '\phpbb\datetime'), $this->php_ini, $this->mimetype_guesser);
110
111        $this->storage = $this->createMock('\phpbb\storage\storage');
112        $this->storage->expects($this->any())
113            ->method('free_space')
114            ->willReturn(1024*1024); // 1gb
115
116        $factory_mock = $this->getMockBuilder('\phpbb\files\factory')
117            ->disableOriginalConstructor()
118            ->getMock();
119        $factory_mock->expects($this->any())
120            ->method('get')
121            ->willReturn(new \phpbb\files\filespec_storage(
122                $this->language,
123                new \FastImageSize\FastImageSize(),
124                $this->mimetype_guesser
125            ));
126
127        $this->container = new phpbb_mock_container_builder();
128        $this->container->set('files.filespec_storage', new \phpbb\files\filespec_storage(
129            $this->language,
130            new \FastImageSize\FastImageSize(),
131            new \phpbb\mimetype\guesser(array(
132                'mimetype.extension_guesser' => new \phpbb\mimetype\extension_guesser(),
133            ))));
134        $this->container->set('files.types.form', new \phpbb\files\types\form(
135            $factory_mock,
136            $this->language,
137            $this->php_ini,
138            $this->plupload,
139            $this->request
140        ));
141        $this->container->set('files.types.local_storage', new \phpbb\files\types\local_storage(
142            $factory_mock,
143            $this->language,
144            $this->php_ini,
145            $this->request
146        ));
147        $this->factory = new \phpbb\files\factory($this->container);
148        $this->files_upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
149        $this->phpbb_dispatcher = new phpbb_mock_event_dispatcher();
150        $this->temp = new \phpbb\filesystem\temp($this->filesystem, '');
151        $this->user = new \phpbb\user($this->language, '\phpbb\datetime');
152        $this->user->data['user_id'] = ANONYMOUS;
153
154        $this->upload = new \phpbb\attachment\upload(
155            $this->auth,
156            $this->cache,
157            $this->config,
158            $this->files_upload,
159            $this->language,
160            $this->phpbb_dispatcher,
161            $this->plupload,
162            $this->storage,
163            $this->temp,
164            $this->user
165        );
166    }
167
168    public static function data_upload()
169    {
170        return array(
171            array('foobar', 1, false,
172                array(),
173                array(
174                    'error' => array(
175                        'Upload initiated but no valid file upload form found.',
176                    ),
177                    'post_attach'    => false,
178                )
179            ),
180            array('foobar', 1, true,
181                array(
182                    'realname'        => 'foobar.jpg',
183                    'type'            => 'jpg',
184                    'size'            => 100,
185                ),
186                array(
187                    'error' => array(
188                        'NOT_UPLOADED',
189                        'The image file you tried to attach is invalid.',
190                    ),
191                    'post_attach'    => false,
192                    'thumbnail'        => 1,
193                )
194            ),
195            array('foobar', 1, true,
196                // Instead of setting to false or empty array, set default filedata array
197                // as otherwise it throws PHP undefined array key warnings
198                // in different file upload related services
199                array(
200                    'realname'        => null,
201                    'type'            => null,
202                    'size'            => null,
203                ),
204                array(
205                    'error' => array(
206                        'NOT_UPLOADED',
207                    ),
208                    'post_attach'    => false,
209                    'thumbnail'        => 0,
210                )
211            ),
212        );
213    }
214
215    /**
216     * @dataProvider data_upload
217     */
218    public function test_upload($form_name, $forum_id, $local, $filedata, $expected)
219    {
220        $filedata = $this->upload->upload($form_name, $forum_id, $local, '', false, $filedata);
221
222        $this->assertSame($expected, $filedata);
223    }
224
225    public function test_init_error()
226    {
227        $filespec = $this->getMockBuilder('\phpbb\files\filespec_storage')
228            ->disableOriginalConstructor()
229            ->getMock();
230        $filespec->expects($this->any())
231            ->method('init_error')
232            ->willReturn(true);
233        $filespec->expects($this->any())
234            ->method('set_upload_namespace')
235            ->willReturnSelf();
236        $filespec->expects($this->any())
237            ->method('set_upload_ary')
238            ->willReturnSelf();
239        $this->container->set('files.filespec_storage', $filespec);
240        $factory_mock = $this->getMockBuilder('\phpbb\files\factory')
241            ->disableOriginalConstructor()
242            ->getMock();
243        $factory_mock->expects($this->any())
244            ->method('get')
245            ->willReturn($filespec);
246        $this->container->set('files.types.local_storage', new \phpbb\files\types\local_storage(
247            $factory_mock,
248            $this->language,
249            $this->php_ini,
250            $this->request
251        ));
252
253        $this->upload = new \phpbb\attachment\upload(
254            $this->auth,
255            $this->cache,
256            $this->config,
257            $this->files_upload,
258            $this->language,
259            $this->phpbb_dispatcher,
260            $this->plupload,
261            $this->storage,
262            $this->temp,
263            $this->user
264        );
265
266        // Instead of setting to false or empty array, set default filedata array
267        // as otherwise it throws PHP undefined array key warnings
268        // in different file upload related services
269        $filedata = $this->upload->upload('foobar', 1, true, '', false,
270            [
271                'realname'        => null,
272                'type'            => null,
273                'size'            => null,
274            ]
275        );
276
277        $this->assertSame(array(
278            'error'        => array(),
279            'post_attach'    => false,
280        ), $filedata);
281    }
282
283    public static function data_image_upload()
284    {
285        return array(
286            array(false, false, array(),
287                array(
288                    'error'            => array('The image file you tried to attach is invalid.'),
289                    'post_attach'    => false,
290                    'thumbnail'        => 1,
291                )
292            ),
293            array(false, true, array(),
294                array(
295                    'error'            => array('The image file you tried to attach is invalid.'),
296                    'post_attach'    => false,
297                    'thumbnail'        => 1,
298                )
299            ),
300            array(true, false, array(),
301                array(
302                    'error'            => array(),
303                    'post_attach'    => true,
304                    // thumbnail gets reset to 0 as creation was not possible
305                    'thumbnail'        => 0,
306                    'filesize'        => 100,
307                    'mimetype'        => 'jpg',
308                    'extension'        => 'jpg',
309                    'real_filename'    => 'foobar.jpg',
310                )
311            ),
312            array(true, false,
313                array(
314                    'check_attachment_content'    => true,
315                    'mime_triggers'    => '',
316                ),
317                array(
318                    'error'            => array(),
319                    'post_attach'    => true,
320                    // thumbnail gets reset to 0 as creation was not possible
321                    'thumbnail'        => 0,
322                    'filesize'        => 100,
323                    'mimetype'        => 'jpg',
324                    'extension'        => 'jpg',
325                    'real_filename'    => 'foobar.jpg',
326                )
327            ),
328            array(true, false,
329                array(
330                    'attachment_quota'    => 150,
331                ),
332                array(
333                    'error'            => array(),
334                    'post_attach'    => true,
335                    // thumbnail gets reset to 0 as creation was not possible
336                    'thumbnail'        => 0,
337                    'filesize'        => 100,
338                    'mimetype'        => 'jpg',
339                    'extension'        => 'jpg',
340                    'real_filename'    => 'foobar.jpg',
341                )
342            ),
343            array(true, false,
344                array(
345                    'attachment_quota'    => 50,
346                ),
347                array(
348                    'error'            => array(
349                        'ATTACH_QUOTA_REACHED',
350                    ),
351                    'post_attach'    => false,
352                    'thumbnail'        => 1,
353                    'filesize'        => 100,
354                    'mimetype'        => 'jpg',
355                    'extension'        => 'jpg',
356                    'real_filename'    => 'foobar.jpg',
357                )
358            ),
359        );
360    }
361
362    /**
363     * @dataProvider data_image_upload
364     */
365    public function test_image_upload($is_image, $plupload_active, $config_data, $expected)
366    {
367        $filespec = $this->getMockBuilder('\phpbb\files\filespec_storage')
368            ->onlyMethods(array(
369                'init_error',
370                'is_image',
371                'move_file',
372                'is_uploaded',
373            ))
374            ->setConstructorArgs(array(
375                $this->language,
376                new \FastImageSize\FastImageSize(),
377                $this->mimetype_guesser,
378                $this->plupload
379            ))
380            ->getMock();
381        foreach ($config_data as $key => $value)
382        {
383            $this->config[$key] = $value;
384        }
385        $filespec->set_upload_namespace($this->files_upload);
386        $filespec->expects($this->any())
387            ->method('init_error')
388            ->willReturn(false);
389        $filespec->expects($this->any())
390            ->method('is_image')
391            ->willReturn($is_image);
392        $filespec->expects($this->any())
393            ->method('is_uploaded')
394            ->willReturn(true);
395        $filespec->expects($this->any())
396            ->method('move_file')
397            ->willReturn(false);
398        $this->container->set('files.filespec_storage', $filespec);
399        $factory_mock = $this->getMockBuilder('\phpbb\files\factory')
400            ->disableOriginalConstructor()
401            ->getMock();
402        $factory_mock->expects($this->any())
403            ->method('get')
404            ->willReturn($filespec);
405        $this->container->set('files.types.local_storage', new \phpbb\files\types\local_storage(
406            $factory_mock,
407            $this->language,
408            $this->php_ini,
409            $this->request
410        ));
411
412        $plupload = $this->getMockBuilder('\phpbb\plupload\plupload')
413            ->disableOriginalConstructor()
414            ->getMock();
415        $plupload->expects($this->any())
416            ->method('is_active')
417            ->willReturn($plupload_active);
418        if ($plupload_active)
419        {
420            $plupload->expects($this->once())
421                ->method('emit_error')
422                ->with(104, 'ATTACHED_IMAGE_NOT_IMAGE')
423                ->willReturn(false);
424        }
425        $this->upload = new \phpbb\attachment\upload(
426            $this->auth,
427            $this->cache,
428            $this->config,
429            $this->files_upload,
430            $this->language,
431            $this->phpbb_dispatcher,
432            $plupload,
433            $this->storage,
434            $this->temp,
435            $this->user
436        );
437
438        $filedata = $this->upload->upload('foobar', 1, true, '', false, array(
439            'realname'        => 'foobar.jpg',
440            'type'            => 'jpg',
441            'size'            => 100,
442        ));
443
444        foreach ($expected as $key => $entry)
445        {
446            $this->assertEquals($entry, $filedata[$key]);
447        }
448
449        // Reset config data
450        foreach ($config_data as $key => $value)
451        {
452            $this->config->delete($key);
453        }
454    }
455}