Merge branch 'MDL-73852-master' of https://github.com/ilyatregubov/moodle

This commit is contained in:
Huong Nguyen 2023-11-15 09:32:09 +07:00
commit 011a606c13
8 changed files with 408 additions and 0 deletions

View File

@ -0,0 +1,88 @@
@tool @tool_uploadcourse @_file_upload
Feature: An admin can create courses with meta enrolments using a CSV file
In order to create courses using a CSV file with meta enrolment
As an admin
I need to be able to upload a CSV file and navigate through the import process
Background:
Given the following "categories" exist:
| name | category | idnumber |
| Cat 0 | 0 | CAT0 |
| Cat 1 | CAT0 | CAT1 |
| Cat 1 | CAT0 | CAT2 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | CAT1 |
| Course 2 | C2 | CAT1 |
And I log in as "admin"
And I navigate to "Plugins > Enrolments > Manage enrol plugins" in site administration
And I click on "Enable" "link" in the "Course meta link" "table_row"
And I navigate to "Courses > Upload courses" in site administration
And I set the field "Upload mode" to "Create new courses, or update existing ones"
And I set the field "Update mode" to "Update with CSV data only"
@javascript
Scenario: Validation of meta link course shortname for uploaded courses
Given I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_meta.csv" file to "File" filemanager
And I click on "Preview" "button"
And I should see "Unknown meta course shortname"
And I should see "You can not meta link course to itself"
When I click on "Upload courses" "button"
And I should see "Unknown meta course shortname"
And I should see "You can not meta link course to itself"
And I should see "Courses created: 1"
And I should see "Courses updated: 0"
And I should see "Courses errors: 2"
And I am on the "Course 4" "enrolment methods" page
Then I should see "Course meta link (Course 1)"
And I click on "Edit" "link" in the "Course meta link" "table_row"
And the field "Add to group" matches value "None"
And I am on the "Course 1" "enrolment methods" page
And I should not see "Course meta link (Course 1)"
@javascript
Scenario: Validation of groups for uploaded courses with meta enrolments
Given the following "groups" exist:
| name | course | idnumber |
| group1 | C2 | G1 |
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_meta_addtogroup_groupname.csv" file to "File" filemanager
And I click on "Preview" "button"
And I should see "You cannot specify groupname when addtogroup is set."
And I navigate to "Courses > Upload courses" in site administration
And I set the field "Upload mode" to "Create new courses, or update existing ones"
And I set the field "Update mode" to "Update with CSV data only"
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_meta_addtogroup.csv" file to "File" filemanager
And I click on "Preview" "button"
And I click on "Upload courses" "button"
And I should see "Courses created: 2"
And I should see "Courses errors: 0"
And I am on the "Course 3" "enrolment methods" page
And I should see "Course meta link (Course 1)"
And I click on "Edit" "link" in the "Course meta link" "table_row"
And the field "Add to group" matches value "Course 1 course"
And I am on the "Course 3" "groups" page
And I should see "Course 1 course"
And I am on the "Course 4" "enrolment methods" page
And I should see "Course meta link (Course 1)"
And I click on "Edit" "link" in the "Course meta link" "table_row"
And the field "Add to group" matches value "None"
And I am on the "Course 4" "groups" page
And I should not see "Course 1 course"
And I navigate to "Courses > Upload courses" in site administration
And I set the field "Upload mode" to "Create new courses, or update existing ones"
And I set the field "Update mode" to "Update with CSV data only"
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_meta_groups.csv" file to "File" filemanager
And I click on "Preview" "button"
And I should see "Error, invalid group notexist"
When I click on "Upload courses" "button"
And I should see "Error, invalid group notexist"
And I should see "Courses updated: 1"
And I should see "Courses errors: 1"
And I am on the "Course 2" "enrolment methods" page
Then I should see "Course meta link (Course 1)"
And I click on "Edit" "link" in the "Course meta link" "table_row"
And the field "Add to group" matches value "group1"
And I am on the "Course 2" "groups" page
And I should see "group1"

View File

@ -0,0 +1,4 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_metacoursename
C3,Course 3,CAT1,meta,Not exist
C4,Course 4,CAT2,meta,C1
C1,Course 1,CAT1,meta,C1
1 shortname fullname category_idnumber enrolment_1 enrolment_1_metacoursename
2 C3 Course 3 CAT1 meta Not exist
3 C4 Course 4 CAT2 meta C1
4 C1 Course 1 CAT1 meta C1

View File

@ -0,0 +1,3 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_metacoursename,enrolment_1_addtogroup
C3,Course 3,CAT2,meta,C1,1
C4,Course 4,CAT1,meta,C1,0
1 shortname fullname category_idnumber enrolment_1 enrolment_1_metacoursename enrolment_1_addtogroup
2 C3 Course 3 CAT2 meta C1 1
3 C4 Course 4 CAT1 meta C1 0

View File

@ -0,0 +1,2 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_metacoursename,enrolment_1_addtogroup,enrolment_1_groupname
C2,Course 2,CAT1,meta,C1,0,group1
1 shortname fullname category_idnumber enrolment_1 enrolment_1_metacoursename enrolment_1_addtogroup enrolment_1_groupname
2 C2 Course 2 CAT1 meta C1 0 group1

View File

@ -0,0 +1,3 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_metacoursename,enrolment_1_groupname
C2,Course 2,CAT1,meta,C1,notexist
C2,Course 2,CAT1,meta,C1,group1
1 shortname fullname category_idnumber enrolment_1 enrolment_1_metacoursename enrolment_1_groupname
2 C2 Course 2 CAT1 meta C1 notexist
3 C2 Course 2 CAT1 meta C1 group1

View File

@ -37,8 +37,10 @@ $string['nosyncroleids_desc'] = 'By default all course level role assignments ar
$string['pluginname'] = 'Course meta link';
$string['pluginname_desc'] = 'Course meta link enrolment plugin synchronises enrolments and roles in two different courses.';
$string['syncall'] = 'Synchronise all enrolled users';
$string['samemetacourse'] = 'You can not meta link course to itself';
$string['syncall_desc'] = 'If enabled all enrolled users are synchronised even if they have no role in parent course, if disabled only users that have at least one synchronised role are enrolled in child course.';
$string['privacy:metadata:core_group'] = 'Enrol meta plugin can create a new group or use an existing group to add all the participants of the course linked.';
$string['unknownmetacourse'] = 'Unknown meta course shortname';
$string['wscannotcreategroup'] = 'No permission to create group in linked course id = {$a}.';
$string['wsinvalidcourse'] = 'Course id = {$a} does not exist or no permission to link in meta enrolment.';
$string['wsinvalidmetacourse'] = 'Meta course id = {$a} does not exist or no permission to add enrolment instance.';

View File

@ -383,6 +383,143 @@ class enrol_meta_plugin extends enrol_plugin {
return $errors;
}
/**
* Check if data is valid for a given enrolment plugin
*
* @param array $enrolmentdata enrolment data to validate.
* @param int|null $courseid Course ID.
* @return array Errors
*/
public function validate_enrol_plugin_data(array $enrolmentdata, ?int $courseid = null): array {
global $DB;
$errors = [];
if (!enrol_is_enabled('meta')) {
$errors['plugindisabled'] =
new lang_string('plugindisabled', 'plugin');
}
if (isset($enrolmentdata['addtogroup'])) {
$addtogroup = $enrolmentdata['addtogroup'];
if (($addtogroup == 1) || ($addtogroup == 0)) {
if (isset($enrolmentdata['groupname'])) {
$errors['erroraddtogroupgroupname'] =
new lang_string('erroraddtogroupgroupname', 'group');
}
} else {
$errors['erroraddtogroup'] =
new lang_string('erroraddtogroup', 'group');
}
}
if ($courseid) {
$enrolmentdata = $this->fill_enrol_custom_fields($enrolmentdata, $courseid);
if (isset($enrolmentdata['groupname']) && $enrolmentdata['groupname']) {
$groupname = $enrolmentdata['groupname'];
if (!groups_get_group_by_name($courseid, $groupname)) {
$errors['errorinvalidgroup'] =
new lang_string('errorinvalidgroup', 'group', $groupname);
}
}
}
if (!isset($enrolmentdata['metacoursename'])) {
$errors['missingmandatoryfields'] =
new lang_string('missingmandatoryfields', 'tool_uploadcourse',
'metacoursename');
} else {
$metacoursename = $enrolmentdata['metacoursename'];
$metacourseid = $DB->get_field('course', 'id', ['shortname' => $metacoursename]);
if (!$metacourseid) {
$errors['unknownmetacourse'] =
new lang_string('unknownmetacourse', 'enrol_meta', $metacoursename);
}
if ($courseid && ($courseid == $metacourseid)) {
$errors['samemetacourse'] =
new lang_string('samemetacourse', 'enrol_meta', $metacoursename);
}
}
return $errors;
}
/**
* Fill custom fields data for a given enrolment plugin.
*
* @param array $enrolmentdata enrolment data.
* @param int $courseid Course ID.
* @return array Updated enrolment data with custom fields info.
*/
public function fill_enrol_custom_fields(array $enrolmentdata, int $courseid): array {
global $DB;
$metacoursename = $enrolmentdata['metacoursename'];
$enrolmentdata['customint1'] =
$DB->get_field('course', 'id', ['shortname' => $metacoursename]);
if (isset($enrolmentdata['addtogroup'])) {
if ($enrolmentdata['addtogroup'] == 0) {
$enrolmentdata['customint2'] = 0;
} else if ($enrolmentdata['addtogroup'] == 1) {
$enrolmentdata['customint2'] = ENROL_META_CREATE_GROUP;
}
} else if (isset($enrolmentdata['groupname'])) {
$enrolmentdata['customint2'] = groups_get_group_by_name($courseid, $enrolmentdata['groupname']);
}
return $enrolmentdata;
}
/**
* Check if enrolment plugin is supported in csv course upload.
*
* @return bool
*/
public function is_csv_upload_supported(): bool {
return true;
}
/**
* Finds matching instances for a given course.
*
* @param array $enrolmentdata enrolment data.
* @param int $courseid Course ID.
* @return stdClass|null Matching instance
*/
public function find_instance(array $enrolmentdata, int $courseid) : ?stdClass {
global $DB;
$instances = enrol_get_instances($courseid, false);
$instance = null;
if (isset($enrolmentdata['metacoursename'])) {
$metacourseid = $DB->get_field('course', 'id', ['shortname' => $enrolmentdata['metacoursename']]);
if ($metacourseid) {
foreach ($instances as $i) {
if ($i->enrol == 'meta' && $i->customint1 == $metacourseid) {
$instance = $i;
break;
}
}
}
}
return $instance;
}
/**
* Add new instance of enrol plugin with custom settings,
* called when adding new instance manually or when adding new course.
* Used for example on course upload.
*
* Not all plugins support this.
*
* @param stdClass $course Course object
* @param array|null $fields instance fields
* @return int|null id of new instance or null if not supported
*/
public function add_custom_instance(stdClass $course, ?array $fields = null): ?int {
return $this->add_instance($course, $fields);
}
/**
* Restore instance and map settings.

View File

@ -15,6 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace enrol_meta;
use core\plugininfo\enrol;
/**
* Meta enrolment sync functional test.
@ -1049,4 +1050,172 @@ class plugin_test extends \advanced_testcase {
$this->assertArrayNotHasKey('customint1', $errors);
$this->assertArrayNotHasKey('customint2', $errors);
}
/**
* Test the behaviour of fill_enrol_custom_fields().
*
* @covers ::fill_enrol_custom_fields
*/
public function test_fill_enrol_custom_fields() {
$this->resetAfterTest();
$metaplugin = enrol_get_plugin('meta');
$cat = $this->getDataGenerator()->create_category();
$course1 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course1']);
$course2 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course2']);
$group = $this->getDataGenerator()->create_group(['courseid' => $course1->id]);
$enrolmentdata['metacoursename'] = $course2->shortname;
$enrolmentdata = $metaplugin->fill_enrol_custom_fields($enrolmentdata, $course1->id);
$this->assertArrayHasKey('customint1', $enrolmentdata);
$this->assertEquals($course2->id, $enrolmentdata['customint1']);
$this->assertArrayNotHasKey('customint2', $enrolmentdata);
$enrolmentdata['metacoursename'] = 'notexist';
$enrolmentdata = $metaplugin->fill_enrol_custom_fields($enrolmentdata, $course1->id);
$this->assertArrayHasKey('customint1', $enrolmentdata);
$this->assertFalse($enrolmentdata['customint1']);
$this->assertArrayNotHasKey('customint2', $enrolmentdata);
$enrolmentdata['metacoursename'] = $course2->shortname;
$enrolmentdata['addtogroup'] = 0;
$enrolmentdata = $metaplugin->fill_enrol_custom_fields($enrolmentdata, $course1->id);
$this->assertArrayHasKey('customint1', $enrolmentdata);
$this->assertEquals($course2->id, $enrolmentdata['customint1']);
$this->assertArrayHasKey('customint2', $enrolmentdata);
$this->assertEquals(0, $enrolmentdata['customint2']);
unset($enrolmentdata['addtogroup']);
$enrolmentdata['groupname'] = $group->name;
$enrolmentdata = $metaplugin->fill_enrol_custom_fields($enrolmentdata, $course1->id);
$this->assertArrayHasKey('customint1', $enrolmentdata);
$this->assertEquals($course2->id, $enrolmentdata['customint1']);
$this->assertArrayHasKey('customint2', $enrolmentdata);
$this->assertEquals($group->id, $enrolmentdata['customint2']);
$enrolmentdata['groupname'] = 'notexist';
$enrolmentdata = $metaplugin->fill_enrol_custom_fields($enrolmentdata, $course1->id);
$this->assertArrayHasKey('customint1', $enrolmentdata);
$this->assertEquals($course2->id, $enrolmentdata['customint1']);
$this->assertArrayHasKey('customint2', $enrolmentdata);
$this->assertFalse($enrolmentdata['customint2']);
}
/**
* Test the behaviour of validate_enrol_plugin_data().
*
* @covers ::validate_enrol_plugin_data
*/
public function test_validate_enrol_plugin_data() {
$this->resetAfterTest();
$cat = $this->getDataGenerator()->create_category();
$course1 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course1']);
$course2 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course2']);
$group1 = $this->getDataGenerator()->create_group(['courseid' => $course1->id, 'name' => 'Group 1']);
enrol::enable_plugin('meta', false);
$metaplugin = enrol_get_plugin('meta');
// Plugin is disabled in system and meta course shortname is missing in csv.
$enrolmentdata = [];
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata);
$this->assertArrayHasKey('plugindisabled', $errors);
$this->assertArrayHasKey('missingmandatoryfields', $errors);
enrol::enable_plugin('meta', true);
// Unknown meta course name.
$enrolmentdata['metacoursename'] = 'test';
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata);
$this->assertArrayHasKey('unknownmetacourse', $errors);
// Meta course is same as original course.
$enrolmentdata['metacoursename'] = 'course1';
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertArrayHasKey('samemetacourse', $errors);
// Non-valid 'addtogroup' option.
$enrolmentdata['metacoursename'] = $course2->shortname;
$enrolmentdata['addtogroup'] = 2;
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertArrayHasKey('erroraddtogroup', $errors);
// Options 'addtogroup' and 'groupname' are not allowed together.
$enrolmentdata['addtogroup'] = 0;
$enrolmentdata['groupname'] = 'test';
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertArrayHasKey('erroraddtogroupgroupname', $errors);
// Group does not exist.
unset($enrolmentdata['addtogroup']);
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertArrayHasKey('errorinvalidgroup', $errors);
// Valid data when trying to create a group.
$enrolmentdata['metacoursename'] = $course2->shortname;
$enrolmentdata['addtogroup'] = 1;
unset($enrolmentdata['groupname']);
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertEmpty($errors);
// Valid data when trying to add to existing group.
$enrolmentdata['groupname'] = $group1->name;
unset($enrolmentdata['addtogroup']);
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertEmpty($errors);
// Valid data when trying without group mode.
$enrolmentdata['addtogroup'] = 0;
unset($enrolmentdata['groupname']);
$errors = $metaplugin->validate_enrol_plugin_data($enrolmentdata, $course1->id);
$this->assertEmpty($errors);
}
/**
* Test the behaviour of find_instance().
*
* @covers ::find_instance
*/
public function test_find_instance() {
global $DB;
$this->resetAfterTest();
$cat = $this->getDataGenerator()->create_category();
$course1 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course1']);
$course2 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course2']);
$course3 = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'course3']);
$metaplugin = enrol_get_plugin('meta');
// Add two meta enrol instances.
$instanceid1 = $metaplugin->add_instance($course1, ['customint1' => $course2->id]);
$instanceid2 = $metaplugin->add_instance($course1, ['customint1' => $course3->id]);
$instance1 = $DB->get_record('enrol', ['id' => $instanceid1]);
$instance2 = $DB->get_record('enrol', ['id' => $instanceid2]);
$enrolmentdata = [];
$instance = $metaplugin->find_instance($enrolmentdata, $course1->id);
$this->assertNull($instance);
// Unknown meta course shortname.
$enrolmentdata['metacoursename'] = 'test';
$instance = $metaplugin->find_instance($enrolmentdata, $course1->id);
$this->assertNull($instance);
$enrolmentdata['metacoursename'] = $course2->shortname;
$instance = $metaplugin->find_instance($enrolmentdata, $course1->id);
$this->assertEquals($instance1->id, $instance->id);
$enrolmentdata['metacoursename'] = $course3->shortname;
$instance = $metaplugin->find_instance($enrolmentdata, $course1->id);
$this->assertEquals($instance2->id, $instance->id);
}
}