Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
phpbb_functional_acp_attachments_test
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 4
90
0.00% covered (danger)
0.00%
0 / 1
 setUp
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 tearDown
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
42
 upload_file
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
2
 test_orphaned_attachments
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
2
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
14/**
15 * @group functional
16 */
17class phpbb_functional_acp_attachments_test extends phpbb_functional_test_case
18{
19    private $path;
20
21    protected function setUp(): void
22    {
23        parent::setUp();
24        $this->path = __DIR__ . '/fixtures/files/';
25        $this->add_lang('posting');
26    }
27
28    protected function tearDown(): void
29    {
30        $iterator = new DirectoryIterator(__DIR__ . '/../../phpBB/files/');
31        foreach ($iterator as $fileinfo)
32        {
33            if (
34                $fileinfo->isDot()
35                || $fileinfo->isDir()
36                || $fileinfo->getFilename() === 'index.htm'
37                || $fileinfo->getFilename() === '.htaccess'
38            )
39            {
40                continue;
41            }
42
43            unlink($fileinfo->getPathname());
44        }
45    }
46
47    private function upload_file($filename, $mimetype)
48    {
49        $crawler = self::$client->request(
50            'GET',
51            'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid
52        );
53
54        $file_form_data = array_merge(['add_file' => $this->lang('ADD_FILE')], $this->get_hidden_fields($crawler, 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid));
55
56        $file = array(
57            'tmp_name' => $this->path . $filename,
58            'name' => $filename,
59            'type' => $mimetype,
60            'size' => filesize($this->path . $filename),
61            'error' => UPLOAD_ERR_OK,
62        );
63
64        $crawler = self::$client->request(
65            'POST',
66            'posting.php?mode=reply&t=1&sid=' . $this->sid,
67            $file_form_data,
68            array('fileupload' => $file)
69        );
70
71        return $crawler;
72    }
73
74    public function test_orphaned_attachments()
75    {
76        $this->login();
77        $this->add_lang(['common', 'acp/common', 'acp/attachments']);
78        $crawler = $this->upload_file('valid.jpg', 'image/jpeg');
79
80        // Ensure there was no error message rendered
81        $this->assertStringNotContainsString('<h2>' . $this->lang('INFORMATION') . '</h2>', $this->get_content());
82
83        // Also the file name should be in the first row of the files table
84        $this->assertEquals('valid.jpg', $crawler->filter('span.file-name > a')->text());
85
86        // Get attach id, the link looks similar to ./download/attachment/3
87        $attach_link = $crawler->filter('span.file-name > a')->attr('href');
88        $matches = [];
89        preg_match('/\/([0-9]+)\/valid\.jpg$/', $attach_link, $matches);
90        $attach_id = (int) $matches[1];
91
92        // Set file time older than 3 hours to consider it orphan
93        $sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
94            SET filetime = filetime - ' . 4*60*60 . '
95            WHERE attach_id = ' . (int) $attach_id;
96        $this->db->sql_query($sql);
97
98        $this->admin_login();
99        $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_attachments&mode=orphan');
100        $this->assertContainsLang('ACP_ORPHAN_ATTACHMENTS_EXPLAIN', $this->get_content());
101        $this->assertStringContainsString('valid.jpg', $crawler->filter('tbody a')->text());
102
103        $form = $crawler->selectButton($this->lang('SUBMIT'))->form([
104            "post_id[$attach_id]"    => 99999, // Random
105        ]);
106        $form["add[$attach_id]"]->tick();
107        $crawler = self::submit($form);
108
109        $this->assertContainsLang('UPLOADING_FILES', $this->get_content());
110        $this->assertStringContainsString($this->lang('UPLOADING_FILE_TO', 'valid.jpg', 99999), $this->get_content());
111        $this->assertStringContainsString($this->lang('UPLOAD_POST_NOT_EXIST', 'valid.jpg', 99999), $crawler->filter('span[class="error"]')->text());
112
113        // Delete the file
114        $form = $crawler->selectButton($this->lang('SUBMIT'))->form();
115        $form["delete[$attach_id]"]->tick();
116        $crawler = self::submit($form);
117
118        $this->assertContainsLang('NOTIFY', $crawler->filter('.successbox')->text());
119        $this->assertStringContainsString(strip_tags($this->lang('LOG_ATTACH_ORPHAN_DEL', 'valid.jpg')), $crawler->filter('.successbox > p')->text());
120    }
121}