Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - https://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace core;
18
 
19
use advanced_testcase;
20
use context_system;
21
 
22
/**
23
 * Unit tests for lib/filestorage/stored_file.php.
24
 *
25
 * @package    core_files
26
 * @category   test
27
 * @covers     \stored_file
28
 * @copyright  2022 Mikhail Golenkov <mikhailgolenkov@catalyst-au.net>
29
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 */
1441 ariadna 31
final class stored_file_test extends advanced_testcase {
1 efrain 32
 
33
    /**
34
     * Test that the rotate_image() method does not rotate
35
     * an image that is not supposed to be rotated.
36
     */
11 efrain 37
    public function test_rotate_image_does_not_rotate_image(): void {
1 efrain 38
        global $CFG;
39
        $this->resetAfterTest();
40
 
41
        $filename = 'testimage.jpg';
42
        $filepath = $CFG->dirroot . '/lib/filestorage/tests/fixtures/' . $filename;
43
        $filerecord = [
44
            'contextid' => context_system::instance()->id,
45
            'component' => 'core',
46
            'filearea'  => 'unittest',
47
            'itemid'    => 0,
48
            'filepath'  => '/',
49
            'filename'  => $filename,
50
        ];
51
        $fs = get_file_storage();
52
        $storedfile = $fs->create_file_from_pathname($filerecord, $filepath);
53
 
54
        $result = $storedfile->rotate_image();
55
        $this->assertIsArray($result);
56
        $this->assertCount(2, $result);
57
        $this->assertFalse($result[0]);
58
        $this->assertFalse($result[1]);
59
    }
60
 
61
    /**
62
     * Test that the rotate_image() method rotates an image
63
     * that is supposed to be rotated.
64
     */
11 efrain 65
    public function test_rotate_image_rotates_image(): void {
1 efrain 66
        global $CFG;
67
        $this->resetAfterTest();
68
 
69
        // This image was manually rotated to be upside down. Also, Orientation, ExifImageWidth
70
        // and ExifImageLength EXIF tags were written into its metadata.
71
        // This is needed to make sure that this image will be rotated by stored_file::rotate_image()
72
        // and stored as a new rotated file.
73
        $filename = 'testimage_rotated.jpg';
74
        $filepath = $CFG->dirroot . '/lib/filestorage/tests/fixtures/' . $filename;
75
        $filerecord = [
76
            'contextid' => context_system::instance()->id,
77
            'component' => 'core',
78
            'filearea'  => 'unittest',
79
            'itemid'    => 0,
80
            'filepath'  => '/',
81
            'filename'  => $filename,
82
        ];
83
        $fs = get_file_storage();
84
        $storedfile = $fs->create_file_from_pathname($filerecord, $filepath);
85
 
86
        list ($rotateddata, $size) = $storedfile->rotate_image();
87
        $this->assertNotFalse($rotateddata);
88
        $this->assertIsArray($size);
89
        $this->assertEquals(1200, $size['width']);
90
        $this->assertEquals(297, $size['height']);
91
    }
92
 
93
    /**
94
     * Ensure that get_content_file_handle returns a valid file handle.
95
     */
96
    public function test_get_psr_stream(): void {
97
        global $CFG;
98
        $this->resetAfterTest();
99
 
100
        $filename = 'testimage.jpg';
101
        $filepath = $CFG->dirroot . '/lib/filestorage/tests/fixtures/' . $filename;
102
        $filerecord = [
103
            'contextid' => context_system::instance()->id,
104
            'component' => 'core',
105
            'filearea'  => 'unittest',
106
            'itemid'    => 0,
107
            'filepath'  => '/',
108
            'filename'  => $filename,
109
        ];
110
        $fs = get_file_storage();
111
        $file = $fs->create_file_from_pathname($filerecord, $filepath);
112
 
113
        $stream = $file->get_psr_stream();
114
        $this->assertInstanceOf(\Psr\Http\Message\StreamInterface::class, $stream);
115
        $this->assertEquals(file_get_contents($filepath), $stream->getContents());
116
        $this->assertFalse($stream->isWritable());
117
        $stream->close();
118
    }
119
 
1441 ariadna 120
    /**
121
     * If the data gets into an incorrect state where a file references itself, this should not
122
     * get into endless recursion (stack overflow) but should throw an exception.
123
     */
124
    public function test_sync_external_file_with_recursive_reference(): void {
125
        global $DB;
126
 
127
        $this->resetAfterTest();
128
 
129
        $fs = get_file_storage();
130
        $filerecord = [
131
            'contextid' => context_system::instance()->id,
132
            'component' => 'core',
133
            'filearea' => 'unittest',
134
            'itemid' => 0,
135
            'filepath' => '/',
136
            'filename' => 'hello.txt',
137
        ];
138
        $file = $fs->create_file_from_string($filerecord, 'hello world');
139
 
140
        $referenceid = $DB->get_field('repository_instances', 'id', ['typeid' => FILE_INTERNAL]);
141
        $referencestr = \file_storage::pack_reference($filerecord);
142
        $copyrecord = [
143
            'contextid' => context_system::instance()->id,
144
            'component' => 'core',
145
            'filearea' => 'unittest',
146
            'itemid' => 1,
147
            'filepath' => '/',
148
            'filename' => 'hello.txt',
149
        ];
150
        $copy = $fs->create_file_from_reference($copyrecord, $referenceid, $referencestr);
151
 
152
        // Hack the original file so that it has the reference id to itself from the copy.
153
        $DB->set_field('files', 'referencefileid', $copy->get_referencefileid(), ['id' => $file->get_id()]);
154
 
155
        // Now sync the original file.
156
        $hackedfile = $fs->get_file_by_id($file->get_id());
157
 
158
        try {
159
            $hackedfile->sync_external_file();
160
            $this->fail('Should not work because this is a recursive reference');
161
        } catch (\moodle_exception $e) {
162
            $this->assertStringContainsString('File references itself: ' . $file->get_id(), $e->getMessage());
163
        }
164
 
165
        // Create another file that references the copy.
166
        $reference2str = \file_storage::pack_reference($copyrecord);
167
        $copy2record = [
168
            'contextid' => context_system::instance()->id,
169
            'component' => 'core',
170
            'filearea' => 'unittest',
171
            'itemid' => 2,
172
            'filepath' => '/',
173
            'filename' => 'hello.txt',
174
        ];
175
        $copy2 = $fs->create_file_from_reference($copy2record, $referenceid, $reference2str);
176
 
177
        // Now we change the original file to reference this second one - 2 levels of redirection.
178
        $DB->set_field('files', 'referencefileid', $copy2->get_referencefileid(), ['id' => $file->get_id()]);
179
 
180
        // Again try to sync the original file.
181
        $hackedfile = $fs->get_file_by_id($file->get_id());
182
 
183
        try {
184
            $hackedfile->sync_external_file();
185
            $this->fail('Should not work because this is a recursive reference');
186
        } catch (\moodle_exception $e) {
187
            $this->assertStringContainsString('File references itself: ' . $file->get_id(), $e->getMessage());
188
        }
189
 
190
        // Put the hacked file back how it started so the situation is valid.
191
        $DB->set_field('files', 'referencefileid', 0, ['id' => $file->get_id()]);
192
        $copy2->sync_external_file();
193
        $copy->sync_external_file();
194
        $file->sync_external_file();
195
    }
196
 
1 efrain 197
}