first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,76 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_backup;
use base_setting;
use base_setting_ui;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot.'/backup/util/settings/tests/settings_test.php');
/**
* Tests for base_setting_ui class.
*
* @package core_backup
* @copyright 2021 Université Rennes 2 {@link https://www.univ-rennes2.fr}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class base_setting_ui_test extends \advanced_testcase {
/**
* Tests set_label().
*
* @return void
*/
public function test_set_label(): void {
$this->resetAfterTest();
$bs = new mock_base_setting('test', base_setting::IS_BOOLEAN);
$bsui = new base_setting_ui($bs);
// Should keep original text string.
$bsui->set_label('Section name');
$this->assertEquals('Section name', $bsui->get_label());
// Should keep original HTML string.
$bsui->set_label('<b>Section name</b>');
$this->assertEquals('<b>Section name</b>', $bsui->get_label());
// Should be converted to text string.
$bsui->set_label(123);
$this->assertSame('123', $bsui->get_label());
// Should be converted to non-breaking space (U+00A0) when label is empty.
$bsui->set_label('');
$this->assertSame("\u{00A0}", $bsui->get_label());
// Should be converted to non-breaking space (U+00A0) when the trimmed label is empty.
$bsui->set_label(" \t\t\n\n\t\t ");
$this->assertSame("\u{00A0}", $bsui->get_label());
// Should clean partially the wrong bits.
$bsui->set_label('<b onmouseover=alert("test")>label</b>');
$this->assertSame('<b>label</b>', $bsui->get_label());
// Should raise an exception when cleaning ends with 100% empty.
$this->expectException(\Exception::class);
$this->expectExceptionMessage('error/setting_invalid_ui_label');
$bsui->set_label('<script>alert("test")</script>');
}
}
@@ -0,0 +1,66 @@
@core @core_backup
Feature: Backup Moodle courses
In order to save and store course contents
As an admin
I need to create backups of courses
Background:
Given the following "courses" exist:
| fullname | shortname | category | numsections | initsections |
| Course 1 | C1 | 0 | 10 | 1 |
| Course 2 | C2 | 0 | 2 | 1 |
And the following "activities" exist:
| activity | course | idnumber | name | intro | section |
| assign | C2 | assign1 | Test assign | Assign description | 1 |
| data | C2 | data1 | Test data | Database description | 2 |
And the following config values are set as admin:
| enableasyncbackup | 0 |
And I log in as "admin"
Scenario: Backup a course providing options
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
Then I should see "Restore"
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
And I should see "URL of backup"
And I should see "Anonymize user information"
@javascript
Scenario: Backup a course with default options
When I backup "Course 1" course using this options:
| Initial | Include calendar events | 0 |
| Initial | Include course logs | 1 |
| Schema | Section 5 | 0 |
| Confirmation | Filename | test_backup.mbz |
Then I should see "Restore"
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
And I should not see "Section 5" in the "region-main" "region"
And I press "Continue"
And I click on "Continue" "button" in the ".bcs-current-course" "css_element"
And "No" "icon" should exist in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' fitem ')][contains(., 'Include calendar events')]" "xpath_element"
And "Include course logs" "checkbox" should exist
And I press "Next"
Scenario: Backup a course without blocks
When I backup "Course 1" course using this options:
| 1 | setting_root_blocks | 0 |
Then I should see "Course backup area"
Scenario: Backup selecting just one section
When I backup "Course 2" course using this options:
| Schema | Test data | 0 |
| Schema | Section 2 | 0 |
| Confirmation | Filename | test_backup.mbz |
Then I should see "Course backup area"
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
And I should not see "Section 2" in the "region-main" "region"
And I press "Continue"
And I click on "Continue" "button" in the ".bcs-current-course" "css_element"
And I press "Next"
And I should see "Test assign"
And I should not see "Test data"
Scenario: Backup a course using the one click backup button
When I perform a quick backup of course "Course 2"
Then I should see "Course backup area"
And I should see "backup-moodle2-course-"
@@ -0,0 +1,105 @@
@core @core_backup @core_h5p @mod_h5pactivity @_switch_iframe @javascript
Feature: Backup xAPI states
In order to save and restore xAPI states
As an admin
I need to create backups with xAPI states and restore them
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
And the following "course" exists:
| fullname | Course 1 |
| shortname | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And the following "activity" exists:
| activity | h5pactivity |
| course | C1 |
| name | Awesome H5P package |
| packagefilepath | h5p/tests/fixtures/filltheblanks.h5p |
And the following config values are set as admin:
| enableasyncbackup | 0 |
# Save state for the student user.
And I am on the "Awesome H5P package" "h5pactivity activity" page logged in as student1
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I set the field with xpath "//input[contains(@aria-label,\"Blank input 1 of 4\")]" to "Narnia"
And I switch to the main frame
And I am on the "Course 1" course page
And I am on the "Awesome H5P package" "h5pactivity activity" page
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And the field with xpath "//input[contains(@aria-label,\"Blank input 1 of 4\")]" matches value "Narnia"
And I log out
Scenario: Content state is backup/restored when user data is included
# Backup and restore the course.
Given I log in as "admin"
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 1 |
| Schema | User data | 1 |
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
# Login as student and confirm xAPI state has been restored.
When I am on the "Course 2" course page logged in as student1
And I click on "Awesome H5P package" "link" in the "region-main" "region"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
Then the field with xpath "//input[contains(@aria-label,\"Blank input 1 of 4\")]" matches value "Narnia"
Scenario: Content state is not restored when user data is not included in the backup
# Backup course without user data and then restore it.
When I log in as "admin"
And I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
# Enrol student to the new course.
And the following "course enrolments" exist:
| user | course | role |
| student1 | C2 | student |
# Login as student and confirm xAPI state hasn't been restored.
And I am on the "Course 2" course page logged in as student1
And I click on "Awesome H5P package" "link" in the "region-main" "region"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
Then the field with xpath "//input[contains(@aria-label,\"Blank input 1 of 4\")]" does not match value "Narnia"
Scenario: Content state is not restored when user data is included in the backup but xAPI state is not restored
# Backup with user data and restore it without user data the course.
Given I log in as "admin"
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include user's state in content such as H5P activities | 0 |
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
# Login as student and confirm xAPI state hasn't been restored.
When I am on the "Course 2" course page logged in as student1
And I click on "Awesome H5P package" "link" in the "region-main" "region"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
Then the field with xpath "//input[contains(@aria-label,\"Blank input 1 of 4\")]" does not match value "Narnia"
Scenario: Content state is not restored when it is not included explicitly in the backup
# Backup course with user data but without xAPI state and then restore it.
When I log in as "admin"
And I backup "Course 1" course using this options:
| Initial | Include user's state in content such as H5P activities | 0 |
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I should see "Awesome H5P package"
# Login as student and confirm xAPI state hasn't been restored.
And I am on the "Course 2" course page logged in as student1
And I click on "Awesome H5P package" "link" in the "region-main" "region"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
Then the field with xpath "//input[contains(@aria-label,\"Blank input 1 of 4\")]" does not match value "Narnia"
+382
View File
@@ -0,0 +1,382 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Backup and restore actions to help behat feature files writting.
*
* @package core_backup
* @category test
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
require_once(__DIR__ . '/../../../../../lib/behat/behat_field_manager.php');
require_once(__DIR__ . '/../../../../../lib/tests/behat/behat_navigation.php');
require_once(__DIR__ . '/../../../../../lib/behat/form_field/behat_form_field.php');
use Behat\Gherkin\Node\TableNode as TableNode,
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException,
Behat\Mink\Exception\ExpectationException as ExpectationException;
/**
* Backup-related steps definitions.
*
* @package core_backup
* @category test
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_backup extends behat_base {
/**
* Backups the specified course using the provided options. If you are interested in restoring this backup would be
* useful to provide a 'Filename' option.
*
* @Given /^I backup "(?P<course_fullname_string>(?:[^"]|\\")*)" course using this options:$/
* @param string $backupcourse
* @param TableNode $options Backup options or false if no options provided
*/
public function i_backup_course_using_this_options($backupcourse, $options = false) {
// We can not use other steps here as we don't know where the provided data
// table elements are used, and we need to catch exceptions contantly.
// Navigate to the course backup page.
$this->execute("behat_navigation::i_am_on_page_instance", [$backupcourse, 'backup']);
// Initial settings.
$this->fill_backup_restore_form($this->get_step_options($options, "Initial"));
$this->execute("behat_forms::press_button", get_string('backupstage1action', 'backup'));
// Schema settings.
$this->fill_backup_restore_form($this->get_step_options($options, "Schema"));
$this->execute("behat_forms::press_button", get_string('backupstage2action', 'backup'));
// Confirmation and review, backup filename can also be specified.
$this->fill_backup_restore_form($this->get_step_options($options, "Confirmation"));
$this->execute("behat_forms::press_button", get_string('backupstage4action', 'backup'));
// Waiting for it to finish.
$this->execute("behat_general::wait_until_the_page_is_ready");
// Last backup continue button.
$this->execute("behat_general::i_click_on", array(get_string('backupstage16action', 'backup'), 'button'));
}
/**
* Performs a quick (one click) backup of a course.
*
* Please note that because you can't set settings with this there is no way to know what the filename
* that was produced was. It contains a timestamp making it hard to find.
*
* @Given /^I perform a quick backup of course "(?P<course_fullname_string>(?:[^"]|\\")*)"$/
* @param string $backupcourse
*/
public function i_perform_a_quick_backup_of_course($backupcourse) {
// We can not use other steps here as we don't know where the provided data
// table elements are used, and we need to catch exceptions contantly.
// Navigate to the course backup page.
$this->execute("behat_navigation::i_am_on_page_instance", [$backupcourse, 'backup']);
// Initial settings.
$this->execute("behat_forms::press_button", get_string('jumptofinalstep', 'backup'));
// Waiting for it to finish.
$this->execute("behat_general::wait_until_the_page_is_ready");
// Last backup continue button.
$this->execute("behat_general::i_click_on", array(get_string('backupstage16action', 'backup'), 'button'));
}
/**
* Imports the specified origin course into the other course using the provided options.
*
* Keeping it separatelly from backup & restore, it the number of
* steps and duplicate code becomes bigger a common method should
* be generalized.
*
* @Given /^I import "(?P<from_course_fullname_string>(?:[^"]|\\")*)" course into "(?P<to_course_fullname_string>(?:[^"]|\\")*)" course using this options:$/
* @param string $fromcourse
* @param string $tocourse
* @param TableNode $options
*/
public function i_import_course_into_course($fromcourse, $tocourse, $options = false) {
// We can not use other steps here as we don't know where the provided data
// table elements are used, and we need to catch exceptions contantly.
// Navigate to the course import page.
$this->execute("behat_navigation::i_am_on_page_instance", [$tocourse, 'import']);
// Select the course.
$fromcourse = behat_context_helper::escape($fromcourse);
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' ics-results ')]" .
"/descendant::tr[contains(., $fromcourse)]" .
"/descendant::input[@type='radio']";
$this->execute('behat_forms::i_set_the_field_with_xpath_to', [$xpath, 1]);
$this->execute("behat_forms::press_button", get_string('continue'));
// Initial settings.
$this->fill_backup_restore_form($this->get_step_options($options, "Initial"));
$this->execute("behat_forms::press_button", get_string('importbackupstage1action', 'backup'));
// Schema settings.
$this->fill_backup_restore_form($this->get_step_options($options, "Schema"));
$this->execute("behat_forms::press_button", get_string('importbackupstage2action', 'backup'));
// Run it.
$this->execute("behat_forms::press_button", get_string('importbackupstage4action', 'backup'));
// Wait to ensure restore is complete.
$this->execute("behat_general::wait_until_the_page_is_ready");
// Continue and redirect to 'to' course.
$this->execute("behat_general::i_click_on", array(get_string('continue'), 'button'));
}
/**
* Restores the backup into the specified course and the provided options.
*
* You should be in the 'Restore' page where the backup is.
*
* @Given /^I restore "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into "(?P<existing_course_fullname_string>(?:[^"]|\\")*)" course using this options:$/
* @param string $backupfilename
* @param string $existingcourse
* @param TableNode $options Restore forms options or false if no options provided
*/
public function i_restore_backup_into_course_using_this_options($backupfilename, $existingcourse, $options = false) {
// Confirm restore.
$this->select_backup($backupfilename);
// The argument should be converted to an xpath literal.
$existingcourse = behat_context_helper::escape($existingcourse);
// Selecting the specified course (we can not call behat_forms::select_radio here as is in another behat subcontext).
$radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-existing-course ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' restore-course-search ')]" .
"/descendant::tr[contains(., $existingcourse)]" .
"/descendant::input[@type='radio']";
$this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element'));
// Pressing the continue button of the restore into an existing course section.
$continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-existing-course ')]" .
"/descendant::input[@type='submit'][@value='" . get_string('continue') . "']";
$this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element'));
// Common restore process using provided key/value options.
$this->process_restore($options);
}
/**
* Restores the specified backup into a new course using the provided options.
*
* You should be in the 'Restore' page where the backup is.
*
* @Given /^I restore "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into a new course using this options:$/
* @param string $backupfilename
* @param TableNode $options Restore forms options or false if no options provided
*/
public function i_restore_backup_into_a_new_course_using_this_options($backupfilename, $options = false) {
// Confirm restore.
$this->select_backup($backupfilename);
// The first category in the list.
$radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-new-course ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' restore-course-search ')]" .
"/descendant::input[@type='radio']";
$this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element'));
// Pressing the continue button of the restore into an existing course section.
$continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-new-course ')]" .
"/descendant::input[@type='submit'][@value='" . get_string('continue') . "']";
$this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element'));
// Common restore process using provided key/value options.
$this->process_restore($options);
}
/**
* Merges the backup into the current course using the provided restore options.
*
* You should be in the 'Restore' page where the backup is.
*
* @Given /^I merge "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into the current course using this options:$/
* @param string $backupfilename
* @param TableNode $options Restore forms options or false if no options provided
*/
public function i_merge_backup_into_the_current_course($backupfilename, $options = false) {
// Confirm restore.
$this->select_backup($backupfilename);
// Merge without deleting radio option.
$radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" .
"/descendant::input[@type='radio'][@name='target'][@value='1']";
$this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element'));
// Pressing the continue button of the restore merging section.
$continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" .
"/descendant::input[@type='submit'][@value='" . get_string('continue') . "']";
$this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element'));
// Common restore process using provided key/value options.
$this->process_restore($options);
}
/**
* Merges the backup into the current course after deleting this contents, using the provided restore options.
*
* You should be in the 'Restore' page where the backup is.
*
* @Given /^I merge "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into the current course after deleting it's contents using this options:$/
* @param string $backupfilename
* @param TableNode $options Restore forms options or false if no options provided
*/
public function i_merge_backup_into_current_course_deleting_its_contents($backupfilename, $options = false) {
// Confirm restore.
$this->select_backup($backupfilename);
// Delete contents radio option.
$radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" .
"/descendant::input[@type='radio'][@name='target'][@value='0']";
$this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element'));
// Pressing the continue button of the restore merging section.
$continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" .
"/descendant::input[@type='submit'][@value='" . get_string('continue') . "']";
$this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element'));
// Common restore process using provided key/value options.
$this->process_restore($options);
}
/**
* Selects the backup to restore.
*
* @throws ExpectationException
* @param string $backupfilename
* @return void
*/
protected function select_backup($backupfilename) {
// Using xpath as there are other restore links before this one.
$exception = new ExpectationException('The "' . $backupfilename . '" backup file can not be found in this page',
$this->getSession());
// The argument should be converted to an xpath literal.
$backupfilename = behat_context_helper::escape($backupfilename);
$xpath = "//tr[contains(., $backupfilename)]/descendant::a[contains(., '" . get_string('restore') . "')]";
$restorelink = $this->find('xpath', $xpath, $exception);
$restorelink->click();
// Confirm the backup contents.
$this->find_button(get_string('continue'))->press();
}
/**
* Executes the common steps of all restore processes.
*
* @param TableNode $options The backup and restore options or false if no options provided
* @return void
*/
protected function process_restore($options) {
// We can not use other steps here as we don't know where the provided data
// table elements are used, and we need to catch exceptions contantly.
// Settings.
$this->fill_backup_restore_form($this->get_step_options($options, "Settings"));
$this->execute("behat_forms::press_button", get_string('restorestage4action', 'backup'));
// Schema.
$this->fill_backup_restore_form($this->get_step_options($options, "Schema"));
$this->execute("behat_forms::press_button", get_string('restorestage8action', 'backup'));
// Review, no options here.
$this->execute("behat_forms::press_button", get_string('restorestage16action', 'backup'));
// Wait till the final button is visible.
$this->execute("behat_general::wait_until_the_page_is_ready");
// Last restore continue button, redirected to restore course after this.
$this->execute("behat_general::i_click_on", array(get_string('restorestage32action', 'backup'), 'button'));
}
/**
* Tries to fill the current page form elements with the provided options.
*
* This step is slow as it spins over each provided option, we are
* not expected to have lots of provided options, anyways, is better
* to be conservative and wait for the elements to appear rather than
* to have false failures.
*
* @param TableNode $options The backup and restore options or false if no options provided
* @return void
*/
protected function fill_backup_restore_form($options) {
// Nothing to fill if no options are provided.
if (!$options) {
return;
}
// If we find any of the provided options in the current form we should set the value.
$datahash = $options->getRowsHash();
foreach ($datahash as $locator => $value) {
$field = behat_field_manager::get_form_field_from_label($locator, $this);
$field->set_value($value);
}
}
/**
* Get the options specific to this step of the backup/restore process.
*
* @param TableNode $options The options table to filter
* @param string $step The name of the step
* @return TableNode The filtered options table
* @throws ExpectationException
*/
protected function get_step_options($options, $step) {
// Nothing to fill if no options are provided.
if (!$options) {
return;
}
$rows = $options->getRows();
$newrows = array();
foreach ($rows as $k => $data) {
if (count($data) !== 3) {
// Not enough information to guess the page.
throw new ExpectationException("The backup/restore step must be specified for all backup options",
$this->getSession());
} else if ($data[0] == $step) {
unset($data[0]);
$newrows[] = $data;
}
}
$pageoptions = new TableNode($newrows);
return $pageoptions;
}
}
@@ -0,0 +1,40 @@
@core @core_backup
Feature: Duplicate activities
In order to set up my course contents quickly
As a teacher
I need to duplicate activities inside the same course
Scenario: Duplicate an activity
Given the following "course" exists:
| fullname | Course 1 |
| shortname | C1 |
| category | 0 |
| initsections | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section |
| data | Test database name | Test database description | C1 | database1 | 1 |
And the following config values are set as admin:
| backup_import_activities | 0 | backup |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I duplicate "Test database name" activity
And I should see "Test database name (copy)"
And I wait until section "1" is available
And I click on "Edit settings" "link" in the "Test database name" activity
And I set the following fields to these values:
| Name | Original database name |
And I press "Save and return to course"
And I click on "Edit settings" "link" in the "Test database name (copy)" activity
And I set the following fields to these values:
| Name | Duplicated database name |
| Description | Duplicated database description |
And I press "Save and return to course"
Then I should see "Original database name" in the "Section 1" "section"
And I should see "Duplicated database name" in the "Section 1" "section"
And "Original database name" "link" should appear before "Duplicated database name" "link"
@@ -0,0 +1,65 @@
@core @core_backup @core_contentbank @core_h5p @contenttype_h5p @_file_upload @javascript
Feature: Import course content bank content
In order to import content from a course contentbank
As a teacher
I need to confirm that errors will not happen
Background:
Given I log in as "admin"
And the following config values are set as admin:
| unaddableblocks | | theme_boost|
And I am on site homepage
And I turn editing mode on
And I add the "Navigation" block if not present
And I configure the "Navigation" block
And I set the following fields to these values:
| Page contexts | Display throughout the entire site |
And I press "Save changes"
And I navigate to "H5P > Manage H5P content types" in site administration
And I upload "h5p/tests/fixtures/ipsums.h5p" file to "H5P content type" filemanager
And I click on "Upload H5P content types" "button" in the "#fitem_id_uploadlibraries" "css_element"
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| Course 2 | C2 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher1 | C2 | editingteacher |
And the following "contentbank content" exist:
| contextlevel | reference | contenttype | user | contentname | filepath |
| Course | C1 | contenttype_h5p | teacher1 | ipsums.h5p | /h5p/tests/fixtures/ipsums.h5p |
And I log out
And I log in as "teacher1"
Scenario: Import content bank content to another course
Given I am on "Course 2" course homepage
And I expand "Site pages" node
And I click on "Content bank" "link"
And I should not see "ipsums.h5p"
When I import "Course 1" course into "Course 2" course using this options:
And I expand "Site pages" node
And I click on "Content bank" "link"
Then I should see "ipsums.h5p"
And I am on "Course 1" course homepage
And I expand "Site pages" node
And I click on "Content bank" "link"
And I should see "ipsums.h5p"
Scenario: User could configure not to import content bank
Given I am on "Course 2" course homepage
And I expand "Site pages" node
And I click on "Content bank" "link"
And I should not see "ipsums.h5p"
When I import "Course 1" course into "Course 2" course using this options:
| Initial | Include content bank content | 0 |
And I expand "Site pages" node
And I click on "Content bank" "link"
Then I should not see "ipsums.h5p"
And I am on "Course 1" course homepage
And I expand "Site pages" node
And I click on "Content bank" "link"
And I should see "ipsums.h5p"
@@ -0,0 +1,57 @@
@core @core_backup
Feature: Import course's contents into another course
In order to move and copy contents between courses
As a teacher
I need to import a course contents into another course selecting what I want to import
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| Course 2 | C2 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher1 | C2 | editingteacher |
Scenario: Import course's contents to another course
Given I log in as "teacher1"
And the following "activities" exist:
| activity | name | course | idnumber |
| data | Test database name | C1 | database1 |
| forum | Test forum name | C1 | forum1 |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| comments | Course | C1 | course-view-* | side-pre |
| blog_recent | Course | C1 | course-view-* | side-pre |
When I import "Course 1" course into "Course 2" course using this options:
Then I should see "Test database name"
And I should see "Test forum name"
And I should see "Comments" in the "Comments" "block"
And I should see "Recent blog entries"
Scenario: Import process with permission option
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| enrol/manual:enrol | Allow | teacher | Course | C1 |
And I log in as "teacher1"
When I import "Course 1" course into "Course 2" course using this options:
| Initial | Include permission overrides | 1 |
And I am on the "Course 1" "permissions" page
Then I should see "Non-editing teacher (1)"
And I set the field "Advanced role override" to "Non-editing teacher (1)"
And I click on "//div[@class='advancedoverride']/div/form/noscript/input" "xpath_element"
And "enrol/manual:enrol" capability has "Allow" permission
Scenario: Import process without permission option
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| enrol/manual:enrol | Allow | teacher | Course | C1 |
And I log in as "teacher1"
When I import "Course 1" course into "Course 2" course using this options:
| Initial | Include permission overrides | 0 |
And I am on the "Course 2" "permissions" page
Then I should see "Non-editing teacher (0)"
@@ -0,0 +1,48 @@
@core @core_backup
Feature: Option to include groups and groupings when importing a course to another course
In order to import a course to another course with groups and groupings
As a teacher
I need an option to include groups and groupings when importing a course to another course
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
| Course 2 | C2 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher1 | C2 | editingteacher |
And the following "groups" exist:
| name | description | course | idnumber |
| Group 1 | Group description | C1 | GROUP1 |
| Group 2 | Group description | C1 | GROUP2 |
And the following "groupings" exist:
| name | course | idnumber |
| Grouping 1 | C1 | GROUPING1 |
| Grouping 2 | C1 | GROUPING2 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
Scenario: Include groups and groupings when importing a course to another course
Given I import "Course 1" course into "Course 2" course using this options:
| Initial | Include groups and groupings | 1 |
When I am on the "Course 2" "groups" page
Then I should see "Group 1"
And I should see "Group 2"
And I am on the "Course 2" "groupings" page
And I should see "Grouping 1"
And I should see "Grouping 2"
Scenario: Do not include groups and groupings when importing a course to another course
Given I import "Course 1" course into "Course 2" course using this options:
| Initial | Include groups and groupings | 0 |
When I am on the "Course 2" "groups" page
Then I should not see "Group 1"
And I should not see "Group 2"
And I am on the "Course 2" "groupings" page
And I should not see "Grouping 1"
And I should not see "Grouping 2"
@@ -0,0 +1,257 @@
@core @core_backup
Feature: Restore Moodle 2 course backups
In order to continue using my stored course contents
As a teacher and an admin
I need to restore them inside other Moodle courses or in new courses
Background:
Given the following "courses" exist:
| fullname | shortname | category | format | numsections | coursedisplay | initsections |
| Course 1 | C1 | 0 | topics | 15 | 1 | 1 |
| Course 2 | C2 | 0 | topics | 5 | 0 | 1 |
| Course 3 | C3 | 0 | topics | 2 | 0 | 1 |
| Course 4 | C4 | 0 | topics | 20 | 0 | 1 |
| Course 5 | C5 | 0 | topics | 15 | 1 | 0 |
And the following "activities" exist:
| activity | course | idnumber | name | intro | section | externalurl |
| assign | C3 | assign1 | Test assign name | Assign description | 1 | |
| data | C3 | data1 | Test database name | Database description | 2 | |
| forum | C1 | 0001 | Test forum name | | 1 | |
| url | C1 | url1 | Test URL name | Test URL description | 3 | http://www.moodle.org |
| forum | C5 | 0005 | Test forum name | | 1 | |
| url | C5 | url5 | Test URL name | Test URL description | 3 | http://www.moodle.org |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| activity_modules | Course | C1 | course-view-* | side-pre |
| activity_modules | Course | C5 | course-view-* | side-pre |
And the following config values are set as admin:
| enableasyncbackup | 0 |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
@javascript
Scenario: Restore a course in another existing course
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
Then I should see "Course 2"
And I should see "Activities" in the "Activities" "block"
And I should see "Test forum name"
@javascript
Scenario: Restore a course in a new course
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 1 restored in a new course |
Then I should see "Course 1 restored in a new course"
And I should see "Activities" in the "Activities" "block"
And I should see "Test forum name"
And I should see "Section 15"
And I should not see "Section 16"
And I navigate to "Settings" in current page administration
And I expand all fieldsets
And the field "id_format" matches value "Custom sections"
And I press "Cancel"
@javascript
Scenario: Restore a backup into the same course
When I backup "Course 3" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
| Schema | Test database name | 0 |
| Schema | Section 2 | 0 |
Then I should see "Course 2"
And I should see "Test assign name"
And I should not see "Test database name"
@javascript
Scenario: Restore a backup into the same course removing it's contents before that
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And the following "activity" exists:
| activity | forum |
| course | C1 |
| section | 1 |
| name | Test forum post backup name |
And I am on the "Course 1" "restore" page
And I merge "test_backup.mbz" backup into the current course after deleting it's contents using this options:
| Schema | Section 3 | 0 |
Then I should see "Course 1"
And I should not see "Section 3"
And I should not see "Test forum post backup name"
And I should see "Activities" in the "Activities" "block"
And I should see "Test forum name"
@javascript
Scenario: Restore a backup into a new course changing the course format afterwards
Given I backup "Course 5" course using this options:
| Confirmation | Filename | test_backup.mbz |
When I restore "test_backup.mbz" backup into a new course using this options:
Then I should see "New section"
And I should see "Test forum name"
And I navigate to "Settings" in current page administration
And I expand all fieldsets
And the field "id_format" matches value "Custom sections"
And I set the following fields to these values:
| id_startdate_day | 1 |
| id_startdate_month | January |
| id_startdate_year | 2020 |
| id_format | Weekly sections |
| id_enddate_enabled | 0 |
And I press "Save and display"
And I should see "1 January - 7 January"
And I should see "Test forum name"
And I navigate to "Settings" in current page administration
And I expand all fieldsets
And the field "id_format" matches value "Weekly sections"
And I set the following fields to these values:
| id_format | Social |
And I press "Save and display"
And I should see "An open forum for chatting about anything you want to"
And I navigate to "Settings" in current page administration
And I expand all fieldsets
And the field "id_format" matches value "Social"
And I press "Cancel"
@javascript
Scenario: Restore a backup in an existing course retaining the backup course settings
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
| Schema | Overwrite course configuration | Yes |
And I navigate to "Settings" in current page administration
And I expand all fieldsets
Then the field "id_format" matches value "Custom sections"
And the field "Course layout" matches value "Show one section per page"
And the field "Course short name" matches value "C1_1"
And I press "Cancel"
And section "3" should be visible
And section "7" should be hidden
And section "15" should be visible
And I should see "Section 15"
And I should not see "Section 16"
And I should see "Test URL name" in the "Section 3" "section"
And I should see "Test forum name" in the "Section 1" "section"
@javascript
Scenario: Restore a backup in an existing course keeping the target course settings
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
| Schema | Overwrite course configuration | No |
And I navigate to "Settings" in current page administration
And I expand all fieldsets
Then the field "id_format" matches value "Custom sections"
And the field "Course short name" matches value "C2"
And the field "Course layout" matches value "Show all sections on one page"
And I press "Cancel"
And section "3" should be visible
And section "7" should be hidden
And section "15" should be visible
And I should see "Section 15"
And I should not see "Section 16"
And I should see "Test URL name" in the "Section 3" "section"
And I should see "Test forum name" in the "Section 1" "section"
@javascript
Scenario: Restore a backup in an existing course deleting contents and retaining the backup course settings
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
| Confirmation | Filename | test_backup.mbz |
And I am on the "Course 2" "restore" page
And I merge "test_backup.mbz" backup into the current course after deleting it's contents using this options:
| Schema | Overwrite course configuration | Yes |
And I navigate to "Settings" in current page administration
And I expand all fieldsets
Then the field "id_format" matches value "Custom sections"
And the field "Course layout" matches value "Show one section per page"
And the field "Course short name" matches value "C1_1"
And I press "Cancel"
And section "3" should be hidden
And section "7" should be hidden
And section "15" should be visible
And I should see "Section 15"
And I should not see "Section 16"
And I should see "Test URL name" in the "Section 3" "section"
And I should see "Test forum name" in the "Section 1" "section"
@javascript
Scenario: Restore a backup in an existing course deleting contents and keeping the current course settings
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
| Confirmation | Filename | test_backup.mbz |
And I am on the "Course 2" "restore" page
And I merge "test_backup.mbz" backup into the current course after deleting it's contents using this options:
| Schema | Overwrite course configuration | No |
And I navigate to "Settings" in current page administration
And I expand all fieldsets
Then the field "id_format" matches value "Custom sections"
And the field "Course short name" matches value "C2"
And the field "Course layout" matches value "Show all sections on one page"
And I press "Cancel"
And section "3" should be hidden
And section "7" should be hidden
And section "15" should be visible
And I should see "Section 15"
And I should not see "Section 16"
And I should see "Test URL name" in the "Section 3" "section"
And I should see "Test forum name" in the "Section 1" "section"
@javascript
Scenario: Restore a backup in an existing course deleting contents decreasing the number of sections
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
| Confirmation | Filename | test_backup.mbz |
And I am on the "Course 4" "restore" page
And I merge "test_backup.mbz" backup into the current course after deleting it's contents using this options:
| Schema | Overwrite course configuration | No |
And I navigate to "Settings" in current page administration
And I expand all fieldsets
Then the field "id_format" matches value "Custom sections"
And the field "Course short name" matches value "C4"
And the field "Course layout" matches value "Show all sections on one page"
And I press "Cancel"
And section "3" should be hidden
And section "7" should be hidden
And section "15" should be visible
And I should see "Section 15"
And I should not see "Section 16"
And I should see "Test URL name" in the "Section 3" "section"
And I should see "Test forum name" in the "Section 1" "section"
@javascript
Scenario: Restore a backup with override permission
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| enrol/manual:enrol | Allow | teacher | Course | C1 |
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include permission overrides | 1 |
Then I am on the "Course 1 copy 1" "permissions" page
And I should see "Non-editing teacher (1)"
And I set the field "Advanced role override" to "Non-editing teacher (1)"
And "enrol/manual:enrol" capability has "Allow" permission
@javascript
Scenario: Restore a backup without override permission
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| enrol/manual:enrol | Allow | teacher | Course | C1 |
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include permission overrides | 0 |
Then I am on the "Course 1 copy 1" "permissions" page
And I should see "Non-editing teacher (0)"
@@ -0,0 +1,124 @@
@core @core_backup
Feature: Restore Moodle 2 course backups with different user data settings
In order to decide upon including user data during backup and restore of courses
As a teacher and an admin
I need to be able to set and override backup and restore settings
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| data | Test database name | n | C1 | data1 |
And the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Test field name | Test field description |
And the following "mod_data > templates" exist:
| database | name |
| data1 | singletemplate |
| data1 | listtemplate |
| data1 | addtemplate |
| data1 | asearchtemplate |
| data1 | rsstemplate |
And the following "mod_data > entries" exist:
| database | user | Test field name |
| data1 | student1 | Student entry |
And the following config values are set as admin:
| enableasyncbackup | 0 |
And I log in as "admin"
And I backup "Course 1" course using this options:
| Initial | Include enrolled users | 1 |
| Confirmation | Filename | test_backup.mbz |
@javascript
Scenario: Restore a backup with user data
# "User data" marks the user data field for the section
# "-" marks the user data field for the data activity
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 1 |
| Schema | User data | 1 |
| Schema | - | 1 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should see "Student entry"
@javascript
Scenario: Restore a backup without user data for data activity
# "User data" marks the user data field for the section
# "-" marks the user data field for the data activity
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 1 |
| Schema | User data | 1 |
| Schema | - | 0 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should not see "Student entry"
@javascript
Scenario: Restore a backup without user data for section and data activity
# "User data" marks the user data field for the section
# "-" marks the user data field for the data activity
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 1 |
| Schema | User data | 0 |
| Schema | - | 0 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should not see "Student entry"
@javascript
Scenario: Restore a backup without user data for section
# "User data" marks the user data field for the section
# "-" marks the user data field for the data activity
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 1 |
| Schema | - | 1 |
| Schema | User data | 0 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should not see "Student entry"
@javascript
Scenario: Restore a backup with user data with local config for including users set to 0
And I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 0 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should not see "Student entry"
@javascript
Scenario: Restore a backup with user data with site config for including users set to 0
Given I navigate to "Courses > Backups > General restore defaults" in site administration
And I set the field "s_restore_restore_general_users" to ""
And I press "Save changes"
And I am on the "Course 1" "restore" page
# "User data" marks the user data field for the section
# "-" marks the user data field for the data activity
And I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 1 |
| Schema | User data | 1 |
| Schema | - | 1 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should see "Student entry"
@javascript
Scenario: Restore a backup with user data with local and site config config for including users set to 0
Given I navigate to "Courses > Backups > General restore defaults" in site administration
And I set the field "s_restore_restore_general_users" to ""
And I press "Save changes"
And I am on the "Course 1" "restore" page
When I restore "test_backup.mbz" backup into a new course using this options:
| Settings | Include enrolled users | 0 |
Then I should see "Test database name"
When I click on "Test database name" "link" in the "region-main" "region"
Then I should not see "Student entry"
+33
View File
@@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_backup;
/**
* ui tests (all)
*
* @package core_backup
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class ui_test extends \basic_testcase {
/**
* Test backup_ui class
*/
public function test_backup_ui(): void {
}
}