See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]
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 namespace tool_recyclebin; 18 19 /** 20 * Recycle bin category tests. 21 * 22 * @package tool_recyclebin 23 * @copyright 2015 University of Kent 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 class category_bin_test extends \advanced_testcase { 27 28 /** 29 * @var \stdClass $course 30 */ 31 protected $course; 32 33 /** 34 * @var \stdClass $coursebeingrestored 35 */ 36 protected $coursebeingrestored; 37 38 /** 39 * Setup for each test. 40 */ 41 protected function setUp(): void { 42 $this->resetAfterTest(); 43 $this->setAdminUser(); 44 45 // We want the category bin to be enabled. 46 set_config('categorybinenable', 1, 'tool_recyclebin'); 47 48 $this->course = $this->getDataGenerator()->create_course(); 49 } 50 51 /** 52 * Check that our hook is called when a course is deleted. 53 */ 54 public function test_pre_course_delete_hook() { 55 global $DB; 56 57 // This simulates a temporary course being cleaned up by a course restore. 58 $this->coursebeingrestored = $this->getDataGenerator()->create_course(); 59 $this->coursebeingrestored->deletesource = 'restore'; 60 61 // Should have nothing in the recycle bin. 62 $this->assertEquals(0, $DB->count_records('tool_recyclebin_category')); 63 64 delete_course($this->course, false); 65 // This should not be added to the recycle bin. 66 delete_course($this->coursebeingrestored, false); 67 68 // Check the course is now in the recycle bin. 69 $this->assertEquals(1, $DB->count_records('tool_recyclebin_category')); 70 71 // Try with the API. 72 $recyclebin = new \tool_recyclebin\category_bin($this->course->category); 73 $this->assertEquals(1, count($recyclebin->get_items())); 74 } 75 76 /** 77 * Check that our hook is called when a course is deleted. 78 */ 79 public function test_pre_course_category_delete_hook() { 80 global $DB; 81 82 // Should have nothing in the recycle bin. 83 $this->assertEquals(0, $DB->count_records('tool_recyclebin_category')); 84 85 delete_course($this->course, false); 86 87 // Check the course is now in the recycle bin. 88 $this->assertEquals(1, $DB->count_records('tool_recyclebin_category')); 89 90 // Now let's delete the course category. 91 $category = \core_course_category::get($this->course->category); 92 $category->delete_full(false); 93 94 // Check that the course was deleted from the category recycle bin. 95 $this->assertEquals(0, $DB->count_records('tool_recyclebin_category')); 96 } 97 98 /** 99 * Test that we can restore recycle bin items. 100 */ 101 public function test_restore() { 102 global $DB; 103 104 delete_course($this->course, false); 105 106 $recyclebin = new \tool_recyclebin\category_bin($this->course->category); 107 foreach ($recyclebin->get_items() as $item) { 108 $recyclebin->restore_item($item); 109 } 110 111 // Check that it was restored and removed from the recycle bin. 112 $this->assertEquals(2, $DB->count_records('course')); // Site course and the course we restored. 113 $this->assertEquals(0, count($recyclebin->get_items())); 114 } 115 116 /** 117 * Test that we can delete recycle bin items. 118 */ 119 public function test_delete() { 120 global $DB; 121 122 delete_course($this->course, false); 123 124 $recyclebin = new \tool_recyclebin\category_bin($this->course->category); 125 foreach ($recyclebin->get_items() as $item) { 126 $recyclebin->delete_item($item); 127 } 128 129 // Item was deleted, so no course was restored. 130 $this->assertEquals(1, $DB->count_records('course')); // Just the site course. 131 $this->assertEquals(0, count($recyclebin->get_items())); 132 } 133 134 /** 135 * Test the cleanup task. 136 */ 137 public function test_cleanup_task() { 138 global $DB; 139 140 // Set the expiry to 1 week. 141 set_config('categorybinexpiry', WEEKSECS, 'tool_recyclebin'); 142 143 delete_course($this->course, false); 144 145 $recyclebin = new \tool_recyclebin\category_bin($this->course->category); 146 147 // Set deleted date to the distant past. 148 foreach ($recyclebin->get_items() as $item) { 149 $item->timecreated = time() - WEEKSECS; 150 $DB->update_record('tool_recyclebin_category', $item); 151 } 152 153 // Create another course to delete. 154 $course = $this->getDataGenerator()->create_course(); 155 delete_course($course, false); 156 157 // Should now be two courses in the recycle bin. 158 $this->assertEquals(2, count($recyclebin->get_items())); 159 160 // Execute cleanup task. 161 $this->expectOutputRegex("/\[tool_recyclebin\] Deleting item '\d+' from the category recycle bin/"); 162 $task = new \tool_recyclebin\task\cleanup_category_bin(); 163 $task->execute(); 164 165 // Task should only have deleted the course where we updated the time. 166 $courses = $recyclebin->get_items(); 167 $this->assertEquals(1, count($courses)); 168 $course = reset($courses); 169 $this->assertEquals('Test course 2', $course->fullname); 170 } 171 172 /** 173 * Provider for test_course_restore_with_userdata() and test_course_restore_without_userdata() 174 * 175 * Used to verify that recycle bin is immune to various settings. Provides plugin, name, value for 176 * direct usage with set_config() 177 */ 178 public function recycle_bin_settings_provider() { 179 return [ 180 'backup/backup_auto_storage moodle' => [[ 181 (object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 0], 182 ]], 183 184 'backup/backup_auto_storage external' => [[ 185 (object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 1], 186 (object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true], 187 ]], 188 189 'backup/backup_auto_storage mixed' => [[ 190 (object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 2], 191 (object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true], 192 ]], 193 194 'restore/restore_general_users moodle' => [[ 195 (object)['plugin' => 'restore', 'name' => 'restore_general_users', 'value' => 0], 196 (object)['plugin' => 'restore', 'name' => 'restore_general_groups', 'value' => 0], 197 ]], 198 ]; 199 } 200 201 /** 202 * Tests that user data is restored when course is restored. 203 * 204 * @dataProvider recycle_bin_settings_provider 205 * @param array $settings array of plugin, name, value stdClass(). 206 */ 207 public function test_course_restore_with_userdata($settings) { 208 global $DB; 209 210 // Force configuration changes from provider. 211 foreach ($settings as $setting) { 212 // Need to create a directory for backup_auto_destination. 213 if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) { 214 $setting->value = make_request_directory(); 215 } 216 set_config($setting->name, $setting->value, $setting->plugin); 217 } 218 219 // We want user data to be included for this test. 220 set_config('backup_auto_users', true, 'backup'); 221 222 $student = $this->getDataGenerator()->create_and_enrol($this->course, 'student'); 223 224 // Delete course. 225 delete_course($this->course, false); 226 $this->assertFalse($DB->record_exists('course', ['id' => $this->course->id])); 227 228 // Verify there is now a backup @ cat recycle bin file area. 229 $recyclebin = new \tool_recyclebin\category_bin($this->course->category); 230 $this->assertEquals(1, count($recyclebin->get_items())); 231 232 // Restore the recycle bin item. 233 $recyclebin->restore_item(current($recyclebin->get_items())); 234 235 // Get the new course. 236 $newcourse = $DB->get_record('course', ['shortname' => $this->course->shortname], '*', MUST_EXIST); 237 238 // Check that it was removed from the recycle bin. 239 $this->assertEquals(0, count($recyclebin->get_items())); 240 241 // Verify that student DOES continue enrolled. 242 $this->assertTrue(is_enrolled(\context_course::instance($newcourse->id), $student->id)); 243 } 244 245 /** 246 * Tests that user data is not restored when course is restored. 247 * 248 * @dataProvider recycle_bin_settings_provider 249 * @param array $settings array of plugin, name, value stdClass(). 250 */ 251 public function test_course_restore_without_userdata($settings) { 252 global $DB; 253 254 // Force configuration changes from provider. 255 foreach ($settings as $setting) { 256 // Need to create a directory for backup_auto_destination. 257 if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) { 258 $setting->value = make_request_directory(); 259 } 260 set_config($setting->name, $setting->value, $setting->plugin); 261 } 262 263 // We want user data to be included for this test. 264 set_config('backup_auto_users', false, 'backup'); 265 266 $student = $this->getDataGenerator()->create_and_enrol($this->course, 'student'); 267 268 // Delete course. 269 delete_course($this->course, false); 270 $this->assertFalse($DB->record_exists('course', ['id' => $this->course->id])); 271 272 // Verify there is now a backup @ cat recycle bin file area. 273 $recyclebin = new \tool_recyclebin\category_bin($this->course->category); 274 $this->assertEquals(1, count($recyclebin->get_items())); 275 276 // Restore the recycle bin item. 277 $recyclebin->restore_item(current($recyclebin->get_items())); 278 279 // Get the new course. 280 $newcourse = $DB->get_record('course', ['shortname' => $this->course->shortname], '*', MUST_EXIST); 281 282 // Check that it was removed from the recycle bin. 283 $this->assertEquals(0, count($recyclebin->get_items())); 284 285 // Verify that student DOES NOT continue enrolled. 286 $this->assertFalse(is_enrolled(\context_course::instance($newcourse->id), $student->id)); 287 } 288 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body