Skip to content

Commit

Permalink
Merge branch 'MOODLE_36_STABLE' into install_36_STABLE
Browse files Browse the repository at this point in the history
  • Loading branch information
AMOS bot committed Apr 10, 2019
2 parents efcf91a + dcaa783 commit 23d1362
Show file tree
Hide file tree
Showing 19 changed files with 367 additions and 64 deletions.
18 changes: 16 additions & 2 deletions admin/tool/recyclebin/classes/category_bin.php
Expand Up @@ -108,18 +108,32 @@ public function store_item($course) {

require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');

// As far as recycle bin is using MODE_AUTOMATED, it observes the backup_auto_storage
// setting (storing backups @ real location. For recycle bin we want to ensure that
// backup files are always stored in Moodle file area. In order to achieve that, we
// hack the setting here via $CFG->forced_plugin_settings, so it won't interfere other
// operations. See MDL-65218 for more information.
// This hack will be removed once recycle bin switches to use its own backup mode, with
// own preferences and 100% appart from MODLE_AUTOMATED.
// TODO: Remove this as part of MDL-65228.
$CFG->forced_plugin_settings['backup'] = ['backup_auto_storage' => 0];

// Backup the course.
$user = get_admin();
$controller = new \backup_controller(
\backup::TYPE_1COURSE,
$course->id,
\backup::FORMAT_MOODLE,
\backup::INTERACTIVE_NO,
\backup::MODE_GENERAL,
\backup::MODE_AUTOMATED,
$user->id
);
$controller->execute_plan();

// We don't need the forced setting anymore, hence unsetting it.
// TODO: Remove this as part of MDL-65228.
unset($CFG->forced_plugin_settings['backup']);

// Grab the result.
$result = $controller->get_results();
if (!isset($result['backup_destination'])) {
Expand Down Expand Up @@ -233,7 +247,7 @@ public function restore_item($item) {
$tempdir,
$course->id,
\backup::INTERACTIVE_NO,
\backup::MODE_GENERAL,
\backup::MODE_AUTOMATED,
$user->id,
\backup::TARGET_NEW_COURSE
);
Expand Down
16 changes: 15 additions & 1 deletion admin/tool/recyclebin/classes/course_bin.php
Expand Up @@ -112,6 +112,16 @@ public function store_item($cm) {
return;
}

// As far as recycle bin is using MODE_AUTOMATED, it observes the backup_auto_storage
// setting (storing backups @ real location. For recycle bin we want to ensure that
// backup files are always stored in Moodle file area. In order to achieve that, we
// hack the setting here via $CFG->forced_plugin_settings, so it won't interfere other
// operations. See MDL-65218 for more information.
// This hack will be removed once recycle bin switches to use its own backup mode, with
// own preferences and 100% appart from MODLE_AUTOMATED.
// TODO: Remove this as part of MDL-65228.
$CFG->forced_plugin_settings['backup'] = ['backup_auto_storage' => 0];

// Backup the activity.
$user = get_admin();
$controller = new \backup_controller(
Expand All @@ -124,6 +134,10 @@ public function store_item($cm) {
);
$controller->execute_plan();

// We don't need the forced setting anymore, hence unsetting it.
// TODO: Remove this as part of MDL-65228.
unset($CFG->forced_plugin_settings['backup']);

// Grab the result.
$result = $controller->get_results();
if (!isset($result['backup_destination'])) {
Expand Down Expand Up @@ -344,4 +358,4 @@ public function can_delete() {
$context = \context_course::instance($this->_courseid);
return has_capability('tool/recyclebin:deleteitems', $context);
}
}
}
112 changes: 112 additions & 0 deletions admin/tool/recyclebin/tests/category_bin_test.php
Expand Up @@ -176,4 +176,116 @@ public function test_cleanup_task() {
$course = reset($courses);
$this->assertEquals('Test course 2', $course->fullname);
}

/**
* Provider for test_course_restore_with_userdata() and test_course_restore_without_userdata()
*
* Used to verify that recycle bin is immune to various settings. Provides plugin, name, value for
* direct usage with set_config()
*/
public function recycle_bin_settings_provider() {
return [
'backup/backup_auto_storage moodle' => [[
(object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 0],
]],

'backup/backup_auto_storage external' => [[
(object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 1],
(object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true],
]],

'backup/backup_auto_storage mixed' => [[
(object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 2],
(object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true],
]],
];
}

/**
* Tests that user data is restored when course is restored.
*
* @dataProvider recycle_bin_settings_provider
* @param array $settings array of plugin, name, value stdClass().
*/
public function test_course_restore_with_userdata($settings) {
global $DB;

// Force configuration changes from provider.
foreach ($settings as $setting) {
// Need to create a directory for backup_auto_destination.
if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) {
$setting->value = make_request_directory();
}
set_config($setting->name, $setting->value, $setting->plugin);
}

// We want user data to be included for this test.
set_config('backup_auto_users', true, 'backup');

$student = $this->getDataGenerator()->create_and_enrol($this->course, 'student');

// Delete course.
delete_course($this->course, false);
$this->assertFalse($DB->record_exists('course', ['id' => $this->course->id]));

// Verify there is now a backup @ cat recycle bin file area.
$recyclebin = new \tool_recyclebin\category_bin($this->course->category);
$this->assertEquals(1, count($recyclebin->get_items()));

// Restore the recycle bin item.
$recyclebin->restore_item(current($recyclebin->get_items()));

// Get the new course.
$newcourse = $DB->get_record('course', ['shortname' => $this->course->shortname], '*', MUST_EXIST);

// Check that it was removed from the recycle bin.
$this->assertEquals(0, count($recyclebin->get_items()));

// Verify that student DOES continue enrolled.
$this->assertTrue(is_enrolled(context_course::instance($newcourse->id), $student->id));
}

/**
* Tests that user data is not restored when course is restored.
*
* @dataProvider recycle_bin_settings_provider
* @param array $settings array of plugin, name, value stdClass().
*/
public function test_course_restore_without_userdata($settings) {
global $DB;

// Force configuration changes from provider.
foreach ($settings as $setting) {
// Need to create a directory for backup_auto_destination.
if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) {
$setting->value = make_request_directory();
}
set_config($setting->name, $setting->value, $setting->plugin);
}

// We want user data to be included for this test.
set_config('backup_auto_users', false, 'backup');

$student = $this->getDataGenerator()->create_and_enrol($this->course, 'student');

// Delete course.
delete_course($this->course, false);
$this->assertFalse($DB->record_exists('course', ['id' => $this->course->id]));

// Verify there is now a backup @ cat recycle bin file area.
$recyclebin = new \tool_recyclebin\category_bin($this->course->category);
$this->assertEquals(1, count($recyclebin->get_items()));

// Restore the recycle bin item.
$recyclebin->restore_item(current($recyclebin->get_items()));

// Get the new course.
$newcourse = $DB->get_record('course', ['shortname' => $this->course->shortname], '*', MUST_EXIST);

// Check that it was removed from the recycle bin.
$this->assertEquals(0, count($recyclebin->get_items()));

// Verify that student DOES NOT continue enrolled.
$this->assertFalse(is_enrolled(context_course::instance($newcourse->id), $student->id));
}
}
52 changes: 50 additions & 2 deletions admin/tool/recyclebin/tests/course_bin_test.php
Expand Up @@ -174,10 +174,46 @@ public function test_cleanup_task() {
$this->assertEquals($book->name, $deletedbook->name);
}

/**
* Provider for test_coursemodule_restore_with_userdata() and test_coursemodule_restore_without_userdata()
*
* Used to verify that recycle bin is immune to various settings. Provides plugin, name, value for
* direct usage with set_config()
*/
public function recycle_bin_settings_provider() {
return [
'backup/backup_auto_storage moodle' => [[
(object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 0],
]],

'backup/backup_auto_storage external' => [[
(object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 1],
(object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true],
]],

'backup/backup_auto_storage mixed' => [[
(object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 2],
(object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true],
]],
];
}

/**
* Tests that user data is restored when module is restored.
*
* @dataProvider recycle_bin_settings_provider
* @param array $settings array of plugin, name, value stdClass().
*/
public function test_coursemodule_restore_with_userdata() {
public function test_coursemodule_restore_with_userdata($settings) {
// Force configuration changes from provider.
foreach ($settings as $setting) {
// Need to create a directory for backup_auto_destination.
if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) {
$setting->value = make_request_directory();
}
set_config($setting->name, $setting->value, $setting->plugin);
}

$student = $this->getDataGenerator()->create_and_enrol($this->course, 'student');
$this->setUser($student);

Expand Down Expand Up @@ -211,8 +247,20 @@ public function test_coursemodule_restore_with_userdata() {

/**
* Tests that user data is not restored when module is restored.
*
* @dataProvider recycle_bin_settings_provider
* @param array $settings array of plugin, name, value stdClass().
*/
public function test_coursemodule_restore_without_userdata() {
public function test_coursemodule_restore_without_userdata($settings) {
// Force configuration changes from provider.
foreach ($settings as $setting) {
// Need to create a directory for backup_auto_destination.
if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) {
$setting->value = make_request_directory();
}
set_config($setting->name, $setting->value, $setting->plugin);
}

$student = $this->getDataGenerator()->create_and_enrol($this->course, 'student');
$this->setUser($student);

Expand Down

0 comments on commit 23d1362

Please sign in to comment.