Differences Between: [Versions 310 and 311]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body