Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://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
declare(strict_types=1);
18
 
19
namespace core\content\export\exportable_items;
20
 
21
use advanced_testcase;
22
use context;
23
use context_system;
24
use core\content\export\zipwriter;
25
use core\content\export\exported_item;
26
use moodle_url;
27
use stdClass;
28
 
29
/**
30
 * Unit tests for the `exportable_filearea` export item class.
31
 *
32
 * @package     core
33
 * @category    test
34
 * @copyright   2020 Andrew Nicols <andrew@nicols.co.uk>
35
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 * @covers      \core\content\exportable_items\exportable_filearea
37
 */
38
class exportable_filearea_test extends advanced_testcase {
39
 
40
    /**
41
     * Ensure that the the exportable_filearea does not fetch files when none exist.
42
     */
43
    public function test_no_files(): void {
44
        $exportable = new exportable_filearea(
45
            context_system::instance(),
46
            'fake',
47
            'Some fake filearea',
48
            'filearea',
49
            1
50
        );
51
 
52
        $this->assertInstanceOf(exportable_filearea::class, $exportable);
53
    }
54
 
55
    /**
56
     * Ensure that the exportable_filearea returns all stored_file items for only the specified itemid, but those which
57
     * are not included in the archive receive a pluginfile URL.
58
     */
59
    public function test_specified_itemid_excluded_from_zip(): void {
60
        $this->resetAfterTest(true);
61
 
62
        // Setup for test.
63
        $user = $this->getDataGenerator()->create_user();
64
        $context = context_system::instance();
65
        $component = 'fake';
66
        $filearea = 'myfirstfilearea';
67
 
68
        $files1 = $this->create_files(context_system::instance(), $component, $filearea, 1);
69
        $files2 = $this->create_files(context_system::instance(), $component, $filearea, 2);
70
        $files3 = $this->create_files(context_system::instance(), $component, $filearea, 3);
71
        $otherfiles2 = $this->create_files(context_system::instance(), $component, "other{$filearea}", 2);
72
 
73
        $exportable = new exportable_filearea(
74
            $context,
75
            $component,
76
            'Some filearea description',
77
            $filearea,
78
            2
79
        );
80
 
81
        // There is only one exportable.
82
        $this->assertInstanceOf(exportable_filearea::class, $exportable);
83
 
84
        $file2 = reset($files2);
85
        $item = $this->assert_exportable_matches_file($component, $user, $context, $filearea, '', $files2, false, $exportable);
86
        $this->assertCount(count($files2), $item->get_all_files());
87
        $comparisonurl = new moodle_url('/tokenpluginfile.php/');
88
        foreach ($item->get_all_files() as $url) {
89
            $this->assertStringStartsWith($comparisonurl->out(false), $url->filepath);
90
        }
91
    }
92
 
93
    /**
94
     * Ensure that the exportable_filearea returns all stored_file items for only the specified itemid.
95
     */
96
    public function test_specified_itemid(): void {
97
        $this->resetAfterTest(true);
98
 
99
        // Setup for test.
100
        $user = $this->getDataGenerator()->create_user();
101
        $context = context_system::instance();
102
        $component = 'fake';
103
        $filearea = 'myfirstfilearea';
104
 
105
        $files1 = $this->create_files(context_system::instance(), $component, $filearea, 1);
106
        $files2 = $this->create_files(context_system::instance(), $component, $filearea, 2);
107
        $files3 = $this->create_files(context_system::instance(), $component, $filearea, 3);
108
        $otherfiles2 = $this->create_files(context_system::instance(), $component, "other{$filearea}", 2);
109
 
110
        $exportable = new exportable_filearea(
111
            $context,
112
            $component,
113
            'Some filearea description',
114
            $filearea,
115
            2
116
        );
117
 
118
        // There is only one exportable.
119
        $this->assertInstanceOf(exportable_filearea::class, $exportable);
120
 
121
        $file2 = reset($files2);
122
        $item = $this->assert_exportable_matches_file($component, $user, $context, $filearea, '', $files2, true, $exportable);
123
        $this->assertCount(count($files2), $item->get_all_files());
124
    }
125
 
126
    /**
127
     * Ensure that the exportable_filearea returns all stored_files into the correct file location.
128
     */
129
    public function test_in_subdir(): void {
130
        $this->resetAfterTest(true);
131
 
132
        // Setup for test.
133
        $user = $this->getDataGenerator()->create_user();
134
        $context = context_system::instance();
135
        $component = 'fake';
136
        $filearea = 'myfirstfilearea';
137
        $subdir = 'a/path/to/my/subdir';
138
 
139
        $files1 = $this->create_files(context_system::instance(), $component, $filearea, 1);
140
        $files2 = $this->create_files(context_system::instance(), $component, $filearea, 2);
141
        $files3 = $this->create_files(context_system::instance(), $component, $filearea, 3);
142
 
143
        $exportable = new exportable_filearea(
144
            $context,
145
            $component,
146
            'Some filearea description',
147
            $filearea,
148
            2,
149
            2,
150
            $subdir
151
        );
152
 
153
        // There is only one exportable.
154
        $this->assertInstanceOf(exportable_filearea::class, $exportable);
155
 
156
        $item = $this->assert_exportable_matches_file($component, $user, $context, $filearea, $subdir, $files2, true, $exportable);
157
        $this->assertCount(count($files2), $item->get_all_files());
158
    }
159
 
160
    /**
161
     * Create files for use in testing.
162
     *
163
     * @param   context $context
164
     * @param   string $component
165
     * @param   string $filearea
166
     * @param   int $itemid
167
     * @param   int $count
168
     * @return  filearea[]
169
     */
170
    protected function create_files(context $context, string $component, string $filearea, int $itemid, int $count = 1): array {
171
        $fs = get_file_storage();
172
 
173
        $files = [];
174
        for ($i = 0; $i < $count; $i++) {
175
 
176
            $filepath = '/';
177
            for ($j = 0; $j < $i; $j++) {
178
                $filepath .= "{$j}/";
179
            }
180
 
181
            $files[] = $fs->create_file_from_string(
182
                (object) [
183
                    'contextid' => $context->id,
184
                    'component' => $component,
185
                    'filearea' => $filearea,
186
                    'filepath' => $filepath,
187
                    'filename' => "file.txt",
188
                    'itemid' => $itemid,
189
                ],
190
                "File content: {$i}"
191
            );
192
        }
193
 
194
        return $files;
195
    }
196
 
197
    /**
198
     * Assert that the supplied expotable matches the supplied file.
199
     *
200
     * @param   string $component
201
     * @param   stdClass $user
202
     * @param   context $context
203
     * @param   string $filearea
204
     * @param   string $subdir
205
     * @param   stored_file[] $expectedfiles
206
     * @param   bool $addfilestozip Whether to allow files to be added to the archive
207
     * @param   exportable_filearea $exportable
208
     * @return  exported_item
209
     */
210
    protected function assert_exportable_matches_file(
211
        string $component,
212
        stdClass $user,
213
        context $context,
214
        string $filearea,
215
        string $subdir,
216
        array $expectedfiles,
217
        bool $addfilestozip,
218
        exportable_filearea $exportable
219
    ): exported_item {
220
        $archive = $this->getMockBuilder(zipwriter::class)
221
            ->setConstructorArgs([$this->getMockBuilder(\ZipStream\ZipStream::class)->getmock()])
222
            ->onlyMethods([
223
                'add_file_from_stored_file',
224
                'is_file_in_archive',
225
            ])
226
            ->getMock();
227
 
228
        $archive->expects($this->any())
229
            ->method('is_file_in_archive')
230
            ->willReturn($addfilestozip);
231
 
232
        $storedfileargs = [];
233
        foreach ($expectedfiles as $file) {
234
            $filepathinzip = $subdir . '/' . $file->get_filearea() . '/' . $file->get_filepath() . $file->get_filename();
235
            $filepathinzip = ltrim(preg_replace('#/+#', '/', $filepathinzip), '/');
236
            $storedfileargs[] = [
237
                $this->equalTo($context),
238
                $this->equalTo($filepathinzip),
239
                $this->equalTo($file),
240
            ];
241
        }
242
 
243
        $archive->expects($this->exactly(count($expectedfiles)))
244
            ->method('add_file_from_stored_file')
245
            ->withConsecutive(...$storedfileargs);
246
 
247
        return $exportable->add_to_archive($archive);
248
    }
249
}