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
+95
View File
@@ -0,0 +1,95 @@
@enrol @enrol_manual
Feature: A teacher can manage manually enrolled users in their course
In order to manage manually enrolled students in my course
As a teacher
I can manually add and remove users in my course
Background:
Given the following "custom profile fields" exist:
| datatype | shortname | name |
| text | fruit | Fruit |
And the following "users" exist:
| username | firstname | middlename | lastname | email | profile_field_fruit |
| teacher | Teacher | | User | teacher@example.com | |
| user1 | First | Alice | User | first@example.com | Apple |
| user2 | Second | Bob | User | second@example.com | Banana |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher | C1 | editingteacher |
@javascript
Scenario Outline: Manually enrolling users should observe alternative fullname format
Given the following config values are set as admin:
| alternativefullnameformat | firstname middlename lastname |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/site:viewfullnames | <permission> | editingteacher | Course | C1 |
When I am on the "Course 1" "enrolment methods" page logged in as "teacher"
And I click on "Enrol users" "link" in the "Manual enrolments" "table_row"
And I set the field "addselect_searchtext" to "First"
And I wait "1" seconds
And I set the field "Not enrolled users" to "<expectedfullname> (first@example.com)"
And I press "Add"
Then the "Enrolled users" select box should contain "<expectedfullname> (first@example.com)"
Examples:
| permission | expectedfullname |
| Allow | First Alice User |
| Prohibit | First User |
@javascript
Scenario Outline: Manually unenrolling users should observe alternative fullname format
Given the following config values are set as admin:
| alternativefullnameformat | firstname middlename lastname |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/site:viewfullnames | <permission> | editingteacher | Course | C1 |
And the following "course enrolments" exist:
| user | course | role |
| user1 | C1 | student |
| user2 | C1 | student |
When I am on the "Course 1" "enrolment methods" page logged in as "teacher"
And I click on "Enrol users" "link" in the "Manual enrolments" "table_row"
And I set the field "removeselect_searchtext" to "First"
And I wait "1" seconds
And I set the field "Enrolled users" to "<expectedfullname> (first@example.com)"
And I press "Remove"
Then the "Not enrolled users" select box should contain "<expectedfullname> (first@example.com)"
Examples:
| permission | expectedfullname |
| Allow | First Alice User |
| Prohibit | First User |
@javascript
Scenario: Manually enrol users in course using custom user profile fields
Given the following config values are set as admin:
| showuseridentity | email,profile_field_fruit |
When I am on the "Course 1" "enrolment methods" page logged in as "teacher"
And I click on "Enrol users" "link" in the "Manual enrolments" "table_row"
Then the "Not enrolled users" select box should contain "Second User (second@example.com\, Banana)"
And I set the field "addselect_searchtext" to "Apple"
And I wait "1" seconds
And the "Not enrolled users" select box should not contain "Second User (second@example.com\, Banana)"
And I set the field "Not enrolled users" to "First User (first@example.com\, Apple)"
And I press "Add"
And the "Enrolled users" select box should contain "First User (first@example.com\, Apple)"
@javascript
Scenario: Manually unenrol users in course using custom user profile fields
Given the following config values are set as admin:
| showuseridentity | email,profile_field_fruit |
And the following "course enrolments" exist:
| user | course | role |
| user1 | C1 | student |
| user2 | C1 | student |
When I am on the "Course 1" "enrolment methods" page logged in as "teacher"
And I click on "Enrol users" "link" in the "Manual enrolments" "table_row"
Then the "Enrolled users" select box should contain "Second User (second@example.com\, Banana)"
And I set the field "removeselect_searchtext" to "Apple"
And I wait "1" seconds
And the "Enrolled users" select box should not contain "Second User (second@example.com\, Banana)"
And I set the field "Enrolled users" to "First User (first@example.com\, Apple)"
And I press "Remove"
And the "Not enrolled users" select box should contain "First User (first@example.com\, Apple)"
@@ -0,0 +1,258 @@
@enrol @enrol_manual
Feature: Teacher can search and enrol users one by one into the course
In order to quickly enrol particular students into my course
As a teacher
I can search for the students and enrol them into the course
Background:
Given the following "custom profile fields" exist:
| datatype | shortname | name |
| text | customid | Custom user id |
And the following "users" exist:
| username | firstname | lastname | email | profile_field_customid |
| teacher001 | Teacher | 001 | teacher001@example.com | |
| student001 | Student | 001 | student001@example.com | Q994 |
| student002 | Student | 002 | student002@example.com | Q008 |
| student003 | Student | 003 | student003@example.com | Z442 |
| student004 | Student | 004 | student004@example.com | |
| student005 | Student | 005 | student005@example.com | |
| student006 | Student | 006 | student006@example.com | |
| student007 | Student | 007 | student007@example.com | |
| student008 | Student | 008 | student008@example.com | |
| student009 | Student | 009 | student009@example.com | |
| student010 | Student | 010 | student010@example.com | |
| student011 | Student | 011 | student011@example.com | |
| student012 | Student | 012 | student012@example.com | |
| student013 | Student | 013 | student013@example.com | |
| student014 | Student | 014 | student014@example.com | |
| student015 | Student | 015 | student015@example.com | |
| student016 | Student | 016 | student016@example.com | |
| student017 | Student | 017 | student017@example.com | |
| student018 | Student | 018 | student018@example.com | |
| student019 | Student | 019 | student019@example.com | |
| student020 | Student | 020 | student020@example.com | |
| student021 | Student | 021 | student021@example.com | |
| student022 | Student | 022 | student022@example.com | |
| student023 | Student | 023 | student023@example.com | |
| student024 | Student | 024 | student024@example.com | |
| student025 | Student | 025 | student025@example.com | |
| student026 | Student | 026 | student026@example.com | |
| student027 | Student | 027 | student027@example.com | |
| student028 | Student | 028 | student028@example.com | |
| student029 | Student | 029 | student029@example.com | |
| student030 | Student | 030 | student030@example.com | |
| student031 | Student | 031 | student031@example.com | |
| student032 | Student | 032 | student032@example.com | |
| student033 | Student | 033 | student033@example.com | |
| student034 | Student | 034 | student034@example.com | |
| student035 | Student | 035 | student035@example.com | |
| student036 | Student | 036 | student036@example.com | |
| student037 | Student | 037 | student037@example.com | |
| student038 | Student | 038 | student038@example.com | |
| student039 | Student | 039 | student039@example.com | |
| student040 | Student | 040 | student040@example.com | |
| student041 | Student | 041 | student041@example.com | |
| student042 | Student | 042 | student042@example.com | |
| student043 | Student | 043 | student043@example.com | |
| student044 | Student | 044 | student044@example.com | |
| student045 | Student | 045 | student045@example.com | |
| student046 | Student | 046 | student046@example.com | |
| student047 | Student | 047 | student047@example.com | |
| student048 | Student | 048 | student048@example.com | |
| student049 | Student | 049 | student049@example.com | |
| student050 | Student | 050 | student050@example.com | |
| student051 | Student | 051 | student051@example.com | |
| student052 | Student | 052 | student052@example.com | |
| student053 | Student | 053 | student053@example.com | |
| student054 | Student | 054 | student054@example.com | |
| student055 | Student | 055 | student055@example.com | |
| student056 | Student | 056 | student056@example.com | |
| student057 | Student | 057 | student057@example.com | |
| student058 | Student | 058 | student058@example.com | |
| student059 | Student | 059 | student059@example.com | |
| student060 | Student | 060 | student060@example.com | |
| student061 | Student | 061 | student061@example.com | |
| student062 | Student | 062 | student062@example.com | |
| student063 | Student | 063 | student063@example.com | |
| student064 | Student | 064 | student064@example.com | |
| student065 | Student | 065 | student065@example.com | |
| student066 | Student | 066 | student066@example.com | |
| student067 | Student | 067 | student067@example.com | |
| student068 | Student | 068 | student068@example.com | |
| student069 | Student | 069 | student069@example.com | |
| student070 | Student | 070 | student070@example.com | |
| student071 | Student | 071 | student071@example.com | |
| student072 | Student | 072 | student072@example.com | |
| student073 | Student | 073 | student073@example.com | |
| student074 | Student | 074 | student074@example.com | |
| student075 | Student | 075 | student075@example.com | |
| student076 | Student | 076 | student076@example.com | |
| student077 | Student | 077 | student077@example.com | |
| student078 | Student | 078 | student078@example.com | |
| student079 | Student | 079 | student079@example.com | |
| student080 | Student | 080 | student080@example.com | |
| student081 | Student | 081 | student081@example.com | |
| student082 | Student | 082 | student082@example.com | |
| student083 | Student | 083 | student083@example.com | |
| student084 | Student | 084 | student084@example.com | |
| student085 | Student | 085 | student085@example.com | |
| student086 | Student | 086 | student086@example.com | |
| student087 | Student | 087 | student087@example.com | |
| student088 | Student | 088 | student088@example.com | |
| student089 | Student | 089 | student089@example.com | |
| student090 | Student | 090 | student090@example.com | |
| student091 | Student | 091 | student091@example.com | |
| student092 | Student | 092 | student092@example.com | |
| student093 | Student | 093 | student093@example.com | |
| student094 | Student | 094 | student094@example.com | |
| student095 | Student | 095 | student095@example.com | |
| student096 | Student | 096 | student096@example.com | |
| student097 | Student | 097 | student097@example.com | |
| student098 | Student | 098 | student098@example.com | |
| student099 | Student | 099 | student099@example.com | |
And the following "courses" exist:
| fullname | shortname | format | startdate |
| Course 001 | C001 | weeks | ##1 month ago## |
And the following "course enrolments" exist:
| user | course | role | timestart |
| teacher001 | C001 | editingteacher | ##1 month ago## |
And I log in as "teacher001"
And I am on "Course 001" course homepage
@javascript
Scenario: Teacher can search and enrol one particular student
Given I navigate to course participants
And I press "Enrol users"
When I set the field "Select users" to "student001"
And I should see "Student 001"
And I click on "Enrol users" "button" in the "Enrol users" "dialogue"
Then I should see "Active" in the "Student 001" "table_row"
And I should see "1 enrolled users"
@javascript
Scenario: Searching for a non-existing user
Given I navigate to course participants
And I press "Enrol users"
And I click on "Select users" "field"
And I type "qwertyuiop"
Then I should see "No suggestions"
@javascript
Scenario: If there are less than 100 matching users, all are displayed for selection
Given I navigate to course participants
And I press "Enrol users"
When I click on "Select users" "field"
And I type "example.com"
Then "Student 099" "autocomplete_suggestions" should exist
@javascript
Scenario: If there are more than 100 matching users, inform there are too many.
Given the following "users" exist:
| username | firstname | lastname | email |
| student100 | Student | 100 | student100@example.com |
| student101 | Student | 101 | student101@example.com |
And I navigate to course participants
And I press "Enrol users"
When I click on "Select users" "field"
And I type "example.com"
Then I should see "Too many users (>100) to show"
@javascript
Scenario: Changing the Maximum users per page setting affects the enrolment pop-up.
Given the following config values are set as admin:
| maxusersperpage | 5 |
And I navigate to course participants
And I press "Enrol users"
When I click on "Select users" "field"
And I type "student00"
Then I should see "Too many users (>5) to show"
@javascript
Scenario: Change the Show user identity setting affects the enrolment pop-up.
Given I log out
When I log in as "admin"
Then the following "users" exist:
| username | firstname | lastname | email | phone1 | phone2 | department | institution | city | country |
| student100 | Student | 100 | student100@example.com | 1234567892 | 1234567893 | ABC1 | ABC2 | CITY1 | GB |
And the following config values are set as admin:
| showuseridentity | idnumber,email,city,country,phone1,phone2,department,institution |
When I am on "Course 001" course homepage
Then I navigate to course participants
And I press "Enrol users"
And I click on "Select users" "field"
And I type "student100@example.com"
Then I should see "student100@example.com, CITY1, GB, 1234567892, 1234567893, ABC1, ABC2"
# Remove identity field in setting User policies
And the following config values are set as admin:
| showuseridentity | idnumber,email,phone1,phone2,department,institution |
And I am on "Course 001" course homepage
And I navigate to course participants
And I press "Enrol users"
And I click on "Select users" "field"
And I type "student100@example.com"
And I should see "student100@example.com, 1234567892, 1234567893, ABC1, ABC2"
@javascript
Scenario: Custom user profile fields work for search and display, if user has permission
Given the following config values are set as admin:
| showuseridentity | email,profile_field_customid |
And I navigate to course participants
And I press "Enrol users"
When I set the field "Select users" to "Q994"
Then I should see "student001@example.com, Q994"
And I click on "Cancel" "button" in the "Enrol users" "dialogue"
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/site:viewuseridentity | Prevent | editingteacher | Course | C001 |
And I press "Enrol users"
# Do this by keyboard because the 'I set the field' step doesn't let you set it to a missing value.
And I press tab
And I press tab
And I press tab
And I type "Q994"
And I should see "No suggestions"
# The following tests are commented out as a result of MDL-66339.
# @javascript
# Scenario: Enrol user from participants page
# Given I navigate to course participants
# # Enrol user to course
# And I press "Enrol users"
# And I set the field "Select users" to "example.com"
# And I expand the "Select users" autocomplete
# When I click on "Student 099" item in the autocomplete list
# Then I should see "Student 099" in the list of options for the "Select users" autocomplete
# And I click on "Show more" "button"
# # Fill data to input duration
# And "input[name='timeend[enabled]'][checked=checked]" "css_element" should not exist
# And the "Enrolment duration" "select" should be enabled
# And I set the field "duration" to "2"
# # Fill data to input end time
# And I set the field "Starting from" to "2"
# And I set the field "timeend[enabled]" to "1"
# And I set the field "timeend[day]" to "10"
# And the "Enrolment duration" "select" should be disabled
# And I click on "Enrol users" "button" in the "Enrol users" "dialogue"
# And I am on "Course 001" course homepage
# And I navigate to course participants
# And I should see "Student 099" in the "participants" "table"
# And I click on "Edit enrolment" "icon" in the "Student 099" "table_row"
# And the field "timeend[day]" matches value "10"
#
# @javascript
# Scenario: Update Enrol user
# Given I am on "Course 001" course homepage
# And I navigate to course participants
# When I click on "Edit enrolment" "icon" in the "Teacher 001" "table_row"
# Then the "Enrolment duration" "select" should be enabled
# # Fill duration
# And "input[name='timeend[enabled]'][checked=checked]" "css_element" should not exist
# And the "Enrolment duration" "select" should be enabled
# And I set the field "duration" to "2"
# # Fill end time
# And I set the field "timeend[enabled]" to "1"
# And I set the field "timeend[day]" to "28"
# And the "Enrolment duration" "select" should be disabled
# And I press "Save changes"
# And I click on "Edit enrolment" "icon" in the "Teacher 001" "table_row"
# And the field "timeend[day]" matches value "28"
@@ -0,0 +1,123 @@
@enrol @enrol_manual
Feature: A course welcome message will be sent to the user when they are enrolled in a course
In order to let the user know they have been enrolled in a course
As a teacher
I want the user to receive a welcome message when they are enrolled in a course
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| manager | Manager | User | manager@example.com |
| teacher | Teacher | User | teacher@example.com |
| user1 | First | User | first@example.com |
| user2 | Second | User | second@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| Course 2 | C2 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| manager | C1 | manager |
| teacher | C1 | editingteacher |
| teacher | C2 | editingteacher |
@javascript
Scenario: Manager should see the new settings for course welcome message
Given I am on the "C1" "Enrolled users" page logged in as manager
And I set the field "Participants tertiary navigation" to "Enrolment methods"
When I click on "Edit" "link" in the "Manual enrolments" "table_row"
Then I should see "Send course welcome message"
And the field "Send course welcome message" matches value "From the course contact"
And I should see "Custom welcome message"
And the field "Custom welcome message" matches value "Dear {$a->fullname}, you have successfully been enrolled to course {$a->coursename}"
And I should see "Accepted formats: Plain text or Moodle-auto format. HTML tags and multi-lang tags are also accepted, as well as the following placeholders:"
And I set the field "Send course welcome message" to "No"
And I should not see "Custom welcome message"
And I should not see "Accepted formats: Plain text or Moodle-auto format. HTML tags and multi-lang tags are also accepted, as well as the following placeholders:"
@javascript
Scenario: Student should not receive a welcome message if the setting is disabled
Given I am on the "C1" "Enrolled users" page logged in as manager
And I set the field "Participants tertiary navigation" to "Enrolment methods"
And I click on "Edit" "link" in the "Manual enrolments" "table_row"
And I set the field "Send course welcome message" to "No"
And I press "Save changes"
And I am on the "C1" "Enrolled users" page logged in as teacher
And I press "Enrol users"
And I set the field "Select users" to "First User"
And I should see "First User"
And I click on "Enrol users" "button" in the "Enrol users" "dialogue"
And I should see "Active" in the "First User" "table_row"
When I am on the "C1" "course" page logged in as user1
Then I should not see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
@javascript
Scenario: Students should receive a welcome message if the setting is enabled - Default message
Given I am on the "C1" "Enrolled users" page logged in as teacher
# Enrol first user to Course 1.
And I press "Enrol users"
And I set the field "Select users" to "First User"
And I should see "First User"
And I click on "Enrol users" "button" in the "Enrol users" "dialogue"
# Enrol second user to Course 2.
And I am on the "C2" "Enrolled users" page
And I press "Enrol users"
And I set the field "Select users" to "Second User"
And I should see "Second User"
And I click on "Enrol users" "button" in the "Enrol users" "dialogue"
# Login as first user and check the notification.
When I am on the "C1" "course" page logged in as user1
Then I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
And I open the notification popover
And I should see "Welcome to Course 1"
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
And I should see "Dear First User, you have successfully been enrolled to course Course 1"
# Login as second user and check the notification.
And I am on the "C1" "course" page logged in as user2
And I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
And I open the notification popover
And I should see "Welcome to Course 2"
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
And I should see "Dear Second User, you have successfully been enrolled to course Course 2"
@javascript
Scenario: Students should receive a welcome message if the setting is enabled - Custom message
Given I am on the "C1" "Enrolled users" page logged in as manager
And I set the field "Participants tertiary navigation" to "Enrolment methods"
And I click on "Edit" "link" in the "Manual enrolments" "table_row"
And I set the field "Custom welcome message" to multiline:
"""
Dear {$a->fullname}, you have successfully been enrolled to course {$a->coursename}.
Your email address: {$a->email}
Your first name: {$a->firstname}
Your last name: {$a->lastname}
Your course role: {$a->courserole}
"""
And I press "Save changes"
# Enrol first user and second user to Course 1.
And the following "course enrolments" exist:
| user | course | role |
| user1 | C1 | student |
| user2 | C1 | student |
# Login as first user and check the notification.
When I am on the "C1" "course" page logged in as user1
Then I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
And I open the notification popover
And I should see "Welcome to Course 1"
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
And I should see "Dear First User, you have successfully been enrolled to course Course 1"
And I should see "Your email address: first@example.com"
And I should see "Your first name: First"
And I should see "Your last name: User"
And I should see "Your course role: student"
# Login as second user and check the notification.
When I am on the "C1" "course" page logged in as user2
Then I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
And I open the notification popover
And I should see "Welcome to Course 1"
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
And I should see "Dear Second User, you have successfully been enrolled to course Course 1"
And I should see "Your email address: second@example.com"
And I should see "Your first name: Second"
And I should see "Your last name: User"
And I should see "Your course role: student"
+298
View File
@@ -0,0 +1,298 @@
<?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 enrol_manual;
use enrol_manual_external;
use externallib_advanced_testcase;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
require_once($CFG->dirroot . '/enrol/manual/externallib.php');
/**
* Enrol manual external PHPunit tests
*
* @package enrol_manual
* @category phpunit
* @copyright 2012 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 2.4
*/
class externallib_test extends externallib_advanced_testcase {
/**
* Test get_enrolled_users
*/
public function test_enrol_users(): void {
global $DB;
$this->resetAfterTest(true);
$user = self::getDataGenerator()->create_user();
$this->setUser($user);
$course1 = self::getDataGenerator()->create_course();
$course2 = self::getDataGenerator()->create_course();
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$context1 = \context_course::instance($course1->id);
$context2 = \context_course::instance($course2->id);
$instance1 = $DB->get_record('enrol', array('courseid' => $course1->id, 'enrol' => 'manual'), '*', MUST_EXIST);
$instance2 = $DB->get_record('enrol', array('courseid' => $course2->id, 'enrol' => 'manual'), '*', MUST_EXIST);
// Set the required capabilities by the external function.
$roleid = $this->assignUserCapability('enrol/manual:enrol', $context1->id);
$this->assignUserCapability('moodle/course:view', $context1->id, $roleid);
$this->assignUserCapability('moodle/role:assign', $context1->id, $roleid);
$this->assignUserCapability('enrol/manual:enrol', $context2->id, $roleid);
$this->assignUserCapability('moodle/course:view', $context2->id, $roleid);
$this->assignUserCapability('moodle/role:assign', $context2->id, $roleid);
core_role_set_assign_allowed($roleid, 3);
// Call the external function.
enrol_manual_external::enrol_users(array(
array('roleid' => 3, 'userid' => $user1->id, 'courseid' => $course1->id),
array('roleid' => 3, 'userid' => $user2->id, 'courseid' => $course1->id),
));
$this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid' => $instance1->id)));
$this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid' => $instance2->id)));
$this->assertTrue(is_enrolled($context1, $user1));
$this->assertTrue(is_enrolled($context1, $user2));
// Call without required capability.
$DB->delete_records('user_enrolments');
$this->unassignUserCapability('enrol/manual:enrol', $context1->id, $roleid);
try {
enrol_manual_external::enrol_users(array(
array('roleid' => 3, 'userid' => $user1->id, 'courseid' => $course1->id),
));
$this->fail('Exception expected if not having capability to enrol');
} catch (\moodle_exception $e) {
$this->assertInstanceOf('required_capability_exception', $e);
$this->assertSame('nopermissions', $e->errorcode);
}
$this->assignUserCapability('enrol/manual:enrol', $context1->id, $roleid);
$this->assertEquals(0, $DB->count_records('user_enrolments'));
// Call with forbidden role.
try {
enrol_manual_external::enrol_users(array(
array('roleid' => 1, 'userid' => $user1->id, 'courseid' => $course1->id),
));
$this->fail('Exception expected if not allowed to assign role.');
} catch (\moodle_exception $e) {
$this->assertSame('wsusercannotassign', $e->errorcode);
}
$this->assertEquals(0, $DB->count_records('user_enrolments'));
// Call for course without manual instance.
$DB->delete_records('user_enrolments');
$DB->delete_records('enrol', array('courseid' => $course2->id));
try {
enrol_manual_external::enrol_users(array(
array('roleid' => 3, 'userid' => $user1->id, 'courseid' => $course1->id),
array('roleid' => 3, 'userid' => $user1->id, 'courseid' => $course2->id),
));
$this->fail('Exception expected if course does not have manual instance');
} catch (\moodle_exception $e) {
$this->assertSame('wsnoinstance', $e->errorcode);
$this->assertSame(
"Manual enrolment plugin instance doesn't exist or is disabled for the course (id = {$course2->id})",
$e->getMessage()
);
}
}
/**
* Test for unerolling a single user.
* @throws coding_exception
* @throws invalid_parameter_exception
* @throws moodle_exception
*/
public function test_unenrol_user_single(): void {
global $CFG, $DB;
require_once($CFG->libdir . '/enrollib.php');
$this->resetAfterTest(true);
// The user who perform the action.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user); // Log this user in.
$enrol = enrol_get_plugin('manual');
// Create a course.
$course = self::getDataGenerator()->create_course();
$coursecontext = \context_course::instance($course->id);
$enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
// Set the capability for the user.
$roleid = $this->assignUserCapability('enrol/manual:enrol', $coursecontext);
$this->assignUserCapability('enrol/manual:unenrol', $coursecontext, $roleid);
$this->assignUserCapability('moodle/course:view', $coursecontext, $roleid);
$this->assignUserCapability('moodle/role:assign', $coursecontext, $roleid);
// Create a student and enrol them into the course.
$student = $this->getDataGenerator()->create_user();
$enrol->enrol_user($enrolinstance, $student->id);
$this->assertTrue(is_enrolled($coursecontext, $student));
// Call the web service to unenrol.
enrol_manual_external::unenrol_users(array(
array('userid' => $student->id, 'courseid' => $course->id),
));
$this->assertFalse(is_enrolled($coursecontext, $student));
}
/**
* Test for unenrolling multiple users.
* @throws coding_exception
* @throws invalid_parameter_exception
* @throws moodle_exception
*/
public function test_unenrol_user_multiple(): void {
global $CFG, $DB;
require_once($CFG->libdir . '/enrollib.php');
$this->resetAfterTest(true);
// The user who perform the action.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user); // Log this user in.
// Create a course.
$course = self::getDataGenerator()->create_course();
$coursecontext = \context_course::instance($course->id);
$enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
// Set the capability for the user.
$roleid = $this->assignUserCapability('enrol/manual:enrol', $coursecontext);
$this->assignUserCapability('enrol/manual:unenrol', $coursecontext, $roleid);
$this->assignUserCapability('moodle/course:view', $coursecontext, $roleid);
$this->assignUserCapability('moodle/role:assign', $coursecontext, $roleid);
$enrol = enrol_get_plugin('manual');
// Create a student and enrol them into the course.
$student1 = $this->getDataGenerator()->create_user();
$enrol->enrol_user($enrolinstance, $student1->id);
$this->assertTrue(is_enrolled($coursecontext, $student1));
$student2 = $this->getDataGenerator()->create_user();
$enrol->enrol_user($enrolinstance, $student2->id);
$this->assertTrue(is_enrolled($coursecontext, $student2));
// Call the web service to unenrol.
enrol_manual_external::unenrol_users(array(
array('userid' => $student1->id, 'courseid' => $course->id),
array('userid' => $student2->id, 'courseid' => $course->id),
));
$this->assertFalse(is_enrolled($coursecontext, $student1));
$this->assertFalse(is_enrolled($coursecontext, $student2));
}
/**
* Test for unenrol capability.
* @throws coding_exception
* @throws invalid_parameter_exception
* @throws moodle_exception
*/
public function test_unenrol_user_error_no_capability(): void {
global $CFG, $DB;
require_once($CFG->libdir . '/enrollib.php');
$this->resetAfterTest(true);
// The user who perform the action.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user); // Log this user in.
// Create a course.
$course = self::getDataGenerator()->create_course();
$coursecontext = \context_course::instance($course->id);
$enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
$enrol = enrol_get_plugin('manual');
// Create a student and enrol them into the course.
$student = $this->getDataGenerator()->create_user();
$enrol->enrol_user($enrolinstance, $student->id);
$this->assertTrue(is_enrolled($coursecontext, $student));
// Call the web service to unenrol.
try {
enrol_manual_external::unenrol_users(array(
array('userid' => $student->id, 'courseid' => $course->id),
));
$this->fail('Exception expected: User cannot log in to the course');
} catch (\Exception $ex) {
$this->assertTrue($ex instanceof \require_login_exception);
}
// Set the capability for the course, then try again.
$roleid = $this->assignUserCapability('moodle/course:view', $coursecontext);
try {
enrol_manual_external::unenrol_users(array(
array('userid' => $student->id, 'courseid' => $course->id),
));
$this->fail('Exception expected: User cannot log in to the course');
} catch (\Exception $ex) {
$this->assertTrue($ex instanceof \required_capability_exception);
}
// Assign unenrol capability.
$this->assignUserCapability('enrol/manual:unenrol', $coursecontext, $roleid);
enrol_manual_external::unenrol_users(array(
array('userid' => $student->id, 'courseid' => $course->id),
));
$this->assertFalse(is_enrolled($coursecontext, $student));
}
/**
* Test for unenrol if user does not exist.
* @throws coding_exception
*/
public function test_unenrol_user_error_not_exist(): void {
global $CFG, $DB;
require_once($CFG->libdir . '/enrollib.php');
$this->resetAfterTest(true);
// The user who perform the action.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user); // Log this user in.
$enrol = enrol_get_plugin('manual');
// Create a course.
$course = self::getDataGenerator()->create_course();
$coursecontext = \context_course::instance($course->id);
$enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
// Set the capability for the user.
$roleid = $this->assignUserCapability('enrol/manual:enrol', $coursecontext);
$this->assignUserCapability('enrol/manual:unenrol', $coursecontext, $roleid);
$this->assignUserCapability('moodle/course:view', $coursecontext, $roleid);
$this->assignUserCapability('moodle/role:assign', $coursecontext, $roleid);
// Create a student and enrol them into the course.
$student = $this->getDataGenerator()->create_user();
$enrol->enrol_user($enrolinstance, $student->id);
$this->assertTrue(is_enrolled($coursecontext, $student));
try {
enrol_manual_external::unenrol_users(array(
array('userid' => $student->id + 1, 'courseid' => $course->id),
));
$this->fail('Exception expected: invalid student id');
} catch (\Exception $ex) {
$this->assertTrue($ex instanceof \invalid_parameter_exception);
}
// Call for course without manual instance.
$DB->delete_records('user_enrolments');
$DB->delete_records('enrol', ['courseid' => $course->id]);
try {
enrol_manual_external::unenrol_users(array(
array('userid' => $student->id + 1, 'courseid' => $course->id),
));
$this->fail('Exception expected if course does not have manual instance');
} catch (\moodle_exception $e) {
$this->assertSame('wsnoinstance', $e->errorcode);
$this->assertSame(
"Manual enrolment plugin instance doesn't exist or is disabled for the course (id = {$course->id})",
$e->getMessage()
);
}
}
}
+945
View File
@@ -0,0 +1,945 @@
<?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/>.
/**
* Manual enrolment tests.
*
* @package enrol_manual
* @category phpunit
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace enrol_manual;
use course_enrolment_manager;
use stdClass;
defined('MOODLE_INTERNAL') || die();
/**
* Manual enrolment tests.
*
* @package enrol_manual
* @category phpunit
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class lib_test extends \advanced_testcase {
/**
* Test enrol migration function used when uninstalling enrol plugins.
*/
public function test_migrate_plugin_enrolments(): void {
global $DB, $CFG;
require_once($CFG->dirroot.'/enrol/manual/locallib.php');
$this->resetAfterTest();
/** @var $manplugin enrol_manual_plugin */
$manplugin = enrol_get_plugin('manual');
// Setup a few courses and users.
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
$this->assertNotEmpty($studentrole);
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
$this->assertNotEmpty($teacherrole);
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$course3 = $this->getDataGenerator()->create_course();
$course4 = $this->getDataGenerator()->create_course();
$course5 = $this->getDataGenerator()->create_course();
$context1 = \context_course::instance($course1->id);
$context2 = \context_course::instance($course2->id);
$context3 = \context_course::instance($course3->id);
$context4 = \context_course::instance($course4->id);
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
$user4 = $this->getDataGenerator()->create_user();
// We expect manual, self and guest instances to be created by default.
$this->assertEquals(5, $DB->count_records('enrol', array('enrol'=>'manual')));
$this->assertEquals(5, $DB->count_records('enrol', array('enrol'=>'self')));
$this->assertEquals(5, $DB->count_records('enrol', array('enrol'=>'guest')));
$this->assertEquals(15, $DB->count_records('enrol', array()));
$this->assertEquals(0, $DB->count_records('user_enrolments', array()));
// Enrol some users to manual instances.
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$DB->delete_records('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'));
$DB->delete_records('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'));
$DB->delete_records('enrol', array('courseid'=>$course5->id, 'enrol'=>'manual'));
$manplugin->enrol_user($maninstance1, $user1->id, $studentrole->id);
$manplugin->enrol_user($maninstance1, $user2->id, $studentrole->id);
$manplugin->enrol_user($maninstance1, $user3->id, $teacherrole->id);
$manplugin->enrol_user($maninstance2, $user3->id, $teacherrole->id);
$this->assertEquals(4, $DB->count_records('user_enrolments', array()));
// Set up some bogus enrol plugin instances and enrolments.
$xxxinstance1 = $DB->insert_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_ENABLED));
$xxxinstance1 = $DB->get_record('enrol', array('id'=>$xxxinstance1));
$xxxinstance3 = $DB->insert_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_DISABLED));
$xxxinstance3 = $DB->get_record('enrol', array('id'=>$xxxinstance3));
$xxxinstance4 = $DB->insert_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_ENABLED));
$xxxinstance4 = $DB->get_record('enrol', array('id'=>$xxxinstance4));
$xxxinstance4b = $DB->insert_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_DISABLED));
$xxxinstance4b = $DB->get_record('enrol', array('id'=>$xxxinstance4b));
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance1->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_SUSPENDED));
role_assign($studentrole->id, $user1->id, $context1->id, 'enrol_xxx', $xxxinstance1->id);
role_assign($teacherrole->id, $user1->id, $context1->id, 'enrol_xxx', $xxxinstance1->id);
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance1->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_ACTIVE));
role_assign($studentrole->id, $user4->id, $context1->id, 'enrol_xxx', $xxxinstance1->id);
$this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance1->id)));
$this->assertEquals(6, $DB->count_records('role_assignments', array('contextid'=>$context1->id)));
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance3->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE));
role_assign($studentrole->id, $user1->id, $context3->id, 'enrol_xxx', $xxxinstance3->id);
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance3->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_SUSPENDED));
$this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance3->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('contextid'=>$context3->id)));
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE));
role_assign($studentrole->id, $user1->id, $context4->id, 'enrol_xxx', $xxxinstance4->id);
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_ACTIVE));
role_assign($studentrole->id, $user2->id, $context4->id, 'enrol_xxx', $xxxinstance4->id);
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4b->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_SUSPENDED));
role_assign($teacherrole->id, $user1->id, $context4->id, 'enrol_xxx', $xxxinstance4b->id);
$DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4b->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_ACTIVE));
role_assign($teacherrole->id, $user4->id, $context4->id, 'enrol_xxx', $xxxinstance4b->id);
$this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4->id)));
$this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4b->id)));
$this->assertEquals(4, $DB->count_records('role_assignments', array('contextid'=>$context4->id)));
// Finally do the migration.
enrol_manual_migrate_plugin_enrolments('xxx');
// Verify results.
$this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual')));
$this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course1->id, 'enrol'=>'xxx')));
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals(ENROL_INSTANCE_DISABLED, $maninstance1->status);
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertEquals(4, $DB->count_records('user_enrolments', array('enrolid'=>$maninstance1->id)));
$this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance1->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'contextid'=>$context1->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user1->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context1->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'contextid'=>$context1->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context1->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'contextid'=>$context1->id)));
$this->assertEquals(5, $DB->count_records('role_assignments', array('contextid'=>$context1->id)));
$this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual')));
$this->assertEquals(0, $DB->count_records('enrol', array('courseid'=>$course2->id, 'enrol'=>'xxx')));
$maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals(ENROL_INSTANCE_ENABLED, $maninstance2->status);
$this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual')));
$this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course3->id, 'enrol'=>'xxx')));
$maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals(ENROL_INSTANCE_DISABLED, $maninstance3->status);
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance3->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance3->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_SUSPENDED)));
$this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$maninstance3->id)));
$this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance3->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'contextid'=>$context3->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('contextid'=>$context3->id)));
$this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual')));
$this->assertEquals(2, $DB->count_records('enrol', array('courseid'=>$course4->id, 'enrol'=>'xxx')));
$maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals(ENROL_INSTANCE_ENABLED, $maninstance4->status);
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance4->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance4->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance4->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_SUSPENDED)));
$this->assertEquals(3, $DB->count_records('user_enrolments', array('enrolid'=>$maninstance4->id)));
$this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4->id)));
$this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4b->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'contextid'=>$context4->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user1->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context4->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'contextid'=>$context4->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>'', 'userid'=>$user4->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context4->id)));
$this->assertEquals(4, $DB->count_records('role_assignments', array('contextid'=>$context4->id)));
$this->assertEquals(0, $DB->count_records('enrol', array('courseid'=>$course5->id, 'enrol'=>'manual')));
$this->assertEquals(0, $DB->count_records('enrol', array('courseid'=>$course5->id, 'enrol'=>'xxx')));
// Make sure wrong params do not produce errors or notices.
enrol_manual_migrate_plugin_enrolments('manual');
enrol_manual_migrate_plugin_enrolments('yyyy');
}
public function test_expired(): void {
global $DB;
$this->resetAfterTest();
/** @var $manualplugin enrol_manual_plugin */
$manualplugin = enrol_get_plugin('manual');
$trace = new \null_progress_trace();
$now = time();
// Prepare some data.
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
$this->assertNotEmpty($studentrole);
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
$this->assertNotEmpty($teacherrole);
$managerrole = $DB->get_record('role', array('shortname'=>'manager'));
$this->assertNotEmpty($managerrole);
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
$user4 = $this->getDataGenerator()->create_user();
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$course3 = $this->getDataGenerator()->create_course();
$context1 = \context_course::instance($course1->id);
$context2 = \context_course::instance($course2->id);
$context3 = \context_course::instance($course3->id);
$this->assertEquals(3, $DB->count_records('enrol', array('enrol'=>'manual')));
$instance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals($studentrole->id, $instance1->roleid);
$instance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals($studentrole->id, $instance2->roleid);
$instance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals($studentrole->id, $instance3->roleid);
$this->assertEquals(0, $DB->count_records('user_enrolments'));
$this->assertEquals(0, $DB->count_records('role_assignments'));
$manualplugin->enrol_user($instance1, $user1->id, $studentrole->id);
$manualplugin->enrol_user($instance1, $user2->id, $studentrole->id);
$manualplugin->enrol_user($instance1, $user3->id, $studentrole->id, 0, $now-60);
$manualplugin->enrol_user($instance3, $user1->id, $studentrole->id, 0, 0);
$manualplugin->enrol_user($instance3, $user2->id, $studentrole->id, 0, $now+60*60);
$manualplugin->enrol_user($instance3, $user3->id, $teacherrole->id, 0, $now-60*60);
role_assign($managerrole->id, $user4->id, $context1->id);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertEquals(7, $DB->count_records('role_assignments'));
$this->assertEquals(5, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$managerrole->id)));
// Execute tests.
$this->assertEquals(ENROL_EXT_REMOVED_KEEP, $manualplugin->get_config('expiredaction'));
$manualplugin->sync($trace, null);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertEquals(7, $DB->count_records('role_assignments'));
$manualplugin->set_config('expiredaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
$manualplugin->sync($trace, $course2->id);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertEquals(7, $DB->count_records('role_assignments'));
$this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>$context1->id, 'userid'=>$user3->id, 'roleid'=>$studentrole->id)));
$this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>$context3->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id)));
$manualplugin->sync($trace, null);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertEquals(5, $DB->count_records('role_assignments'));
$this->assertEquals(4, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
$this->assertEquals(0, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
$this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context1->id, 'userid'=>$user3->id, 'roleid'=>$studentrole->id)));
$this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context3->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id)));
$manualplugin->set_config('expiredaction', ENROL_EXT_REMOVED_UNENROL);
role_assign($studentrole->id, $user3->id, $context1->id);
role_assign($teacherrole->id, $user3->id, $context3->id);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertEquals(7, $DB->count_records('role_assignments'));
$this->assertEquals(5, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$managerrole->id)));
$manualplugin->sync($trace, null);
$this->assertEquals(4, $DB->count_records('user_enrolments'));
$this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$instance1->id, 'userid'=>$user3->id)));
$this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$instance3->id, 'userid'=>$user3->id)));
$this->assertEquals(5, $DB->count_records('role_assignments'));
$this->assertEquals(4, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
$this->assertEquals(0, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$managerrole->id)));
$manualplugin->set_config('expiredaction', ENROL_EXT_REMOVED_SUSPEND);
$manualplugin->enrol_user($instance1, $user3->id, $studentrole->id, 0, $now-60);
$manualplugin->enrol_user($instance3, $user3->id, $teacherrole->id, 0, $now-60*60);
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$maninstance2 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertEquals(7, $DB->count_records('role_assignments'));
$this->assertEquals(5, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_ACTIVE)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance2->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_ACTIVE)));
$manualplugin->sync($trace, null);
$this->assertEquals(6, $DB->count_records('user_enrolments'));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$instance1->id, 'userid'=>$user3->id)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$instance3->id, 'userid'=>$user3->id)));
$this->assertEquals(7, $DB->count_records('role_assignments'));
$this->assertEquals(5, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
$this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_SUSPENDED)));
$this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance2->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_SUSPENDED)));
}
public function test_send_expiry_notifications(): void {
global $DB, $CFG;
$this->resetAfterTest();
$this->preventResetByRollback(); // Messaging does not like transactions...
$trace = new \null_progress_trace();
/** @var $manualplugin enrol_manual_plugin */
$manualplugin = enrol_get_plugin('manual');
$now = time();
$admin = get_admin();
// Note: hopefully nobody executes the unit tests the last second before midnight...
$manualplugin->set_config('expirynotifylast', $now - 60*60*24);
$manualplugin->set_config('expirynotifyhour', 0);
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
$this->assertNotEmpty($studentrole);
$editingteacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'));
$this->assertNotEmpty($editingteacherrole);
$managerrole = $DB->get_record('role', array('shortname'=>'manager'));
$this->assertNotEmpty($managerrole);
$user1 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser1'));
$user2 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser2'));
$user3 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser3'));
$user4 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser4'));
$user5 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser5'));
$user6 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser6'));
$user7 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser6'));
$user8 = $this->getDataGenerator()->create_user(array('lastname'=>'xuser6'));
$course1 = $this->getDataGenerator()->create_course(array('fullname'=>'xcourse1'));
$course2 = $this->getDataGenerator()->create_course(array('fullname'=>'xcourse2'));
$course3 = $this->getDataGenerator()->create_course(array('fullname'=>'xcourse3'));
$course4 = $this->getDataGenerator()->create_course(array('fullname'=>'xcourse4'));
$this->assertEquals(4, $DB->count_records('enrol', array('enrol'=>'manual')));
$instance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$instance1->expirythreshold = 60*60*24*4;
$instance1->expirynotify = 1;
$instance1->notifyall = 1;
$DB->update_record('enrol', $instance1);
$instance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$instance2->expirythreshold = 60*60*24*1;
$instance2->expirynotify = 1;
$instance2->notifyall = 1;
$DB->update_record('enrol', $instance2);
$instance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$instance3->expirythreshold = 60*60*24*1;
$instance3->expirynotify = 1;
$instance3->notifyall = 0;
$DB->update_record('enrol', $instance3);
$instance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$instance4->expirythreshold = 60*60*24*1;
$instance4->expirynotify = 0;
$instance4->notifyall = 0;
$DB->update_record('enrol', $instance4);
$manualplugin->enrol_user($instance1, $user1->id, $editingteacherrole->id, 0, $now + 60*60*24*1, ENROL_USER_SUSPENDED); // Suspended users are not notified.
$manualplugin->enrol_user($instance1, $user2->id, $studentrole->id, 0, $now + 60*60*24*5); // Above threshold are not notified.
$manualplugin->enrol_user($instance1, $user3->id, $studentrole->id, 0, $now + 60*60*24*3 + 60*60); // Less than one day after threshold - should be notified.
$manualplugin->enrol_user($instance1, $user4->id, $studentrole->id, 0, $now + 60*60*24*4 - 60*3); // Less than one day after threshold - should be notified.
$manualplugin->enrol_user($instance1, $user5->id, $studentrole->id, 0, $now + 60*60); // Should have been already notified.
$manualplugin->enrol_user($instance1, $user6->id, $studentrole->id, 0, $now - 60); // Already expired.
$manualplugin->enrol_user($instance1, $user7->id, $editingteacherrole->id);
$manualplugin->enrol_user($instance1, $user8->id, $managerrole->id); // Highest role --> enroller.
$manualplugin->enrol_user($instance2, $user1->id, $studentrole->id);
$manualplugin->enrol_user($instance2, $user2->id, $studentrole->id, 0, $now + 60*60*24*1 + 60*3); // Above threshold are not notified.
$manualplugin->enrol_user($instance2, $user3->id, $studentrole->id, 0, $now + 60*60*24*1 - 60*60); // Less than one day after threshold - should be notified.
$manualplugin->enrol_user($instance3, $user1->id, $editingteacherrole->id);
$manualplugin->enrol_user($instance3, $user2->id, $studentrole->id, 0, $now + 60*60*24*1 + 60); // Above threshold are not notified.
$manualplugin->enrol_user($instance3, $user3->id, $studentrole->id, 0, $now + 60*60*24*1 - 60*60); // Less than one day after threshold - should be notified.
$manualplugin->enrol_user($instance4, $user4->id, $editingteacherrole->id);
$manualplugin->enrol_user($instance4, $user5->id, $studentrole->id, 0, $now + 60*60*24*1 + 60);
$manualplugin->enrol_user($instance4, $user6->id, $studentrole->id, 0, $now + 60*60*24*1 - 60*60);
// The notification is sent out in fixed order first individual users,
// then summary per course by enrolid, user lastname, etc.
$this->assertGreaterThan($instance1->id, $instance2->id);
$this->assertGreaterThan($instance2->id, $instance3->id);
$sink = $this->redirectMessages();
$manualplugin->send_expiry_notifications($trace);
$messages = $sink->get_messages();
$this->assertEquals(2+1 + 1+1 + 1 + 0, count($messages));
// First individual notifications from course1.
$this->assertEquals($user3->id, $messages[0]->useridto);
$this->assertEquals($user8->id, $messages[0]->useridfrom);
$this->assertStringContainsString('xcourse1', $messages[0]->fullmessagehtml);
$this->assertEquals($user4->id, $messages[1]->useridto);
$this->assertEquals($user8->id, $messages[1]->useridfrom);
$this->assertStringContainsString('xcourse1', $messages[1]->fullmessagehtml);
// Then summary for course1.
$this->assertEquals($user8->id, $messages[2]->useridto);
$this->assertEquals($admin->id, $messages[2]->useridfrom);
$this->assertStringContainsString('xcourse1', $messages[2]->fullmessagehtml);
$this->assertStringNotContainsString('xuser1', $messages[2]->fullmessagehtml);
$this->assertStringNotContainsString('xuser2', $messages[2]->fullmessagehtml);
$this->assertStringContainsString('xuser3', $messages[2]->fullmessagehtml);
$this->assertStringContainsString('xuser4', $messages[2]->fullmessagehtml);
$this->assertStringContainsString('xuser5', $messages[2]->fullmessagehtml);
$this->assertStringNotContainsString('xuser6', $messages[2]->fullmessagehtml);
// First individual notifications from course2.
$this->assertEquals($user3->id, $messages[3]->useridto);
$this->assertEquals($admin->id, $messages[3]->useridfrom);
$this->assertStringContainsString('xcourse2', $messages[3]->fullmessagehtml);
// Then summary for course2.
$this->assertEquals($admin->id, $messages[4]->useridto);
$this->assertEquals($admin->id, $messages[4]->useridfrom);
$this->assertStringContainsString('xcourse2', $messages[4]->fullmessagehtml);
$this->assertStringNotContainsString('xuser1', $messages[4]->fullmessagehtml);
$this->assertStringNotContainsString('xuser2', $messages[4]->fullmessagehtml);
$this->assertStringContainsString('xuser3', $messages[4]->fullmessagehtml);
$this->assertStringNotContainsString('xuser4', $messages[4]->fullmessagehtml);
$this->assertStringNotContainsString('xuser5', $messages[4]->fullmessagehtml);
$this->assertStringNotContainsString('xuser6', $messages[4]->fullmessagehtml);
// Only summary in course3.
$this->assertEquals($user1->id, $messages[5]->useridto);
$this->assertEquals($admin->id, $messages[5]->useridfrom);
$this->assertStringContainsString('xcourse3', $messages[5]->fullmessagehtml);
$this->assertStringNotContainsString('xuser1', $messages[5]->fullmessagehtml);
$this->assertStringNotContainsString('xuser2', $messages[5]->fullmessagehtml);
$this->assertStringContainsString('xuser3', $messages[5]->fullmessagehtml);
$this->assertStringNotContainsString('xuser4', $messages[5]->fullmessagehtml);
$this->assertStringNotContainsString('xuser5', $messages[5]->fullmessagehtml);
$this->assertStringNotContainsString('xuser6', $messages[5]->fullmessagehtml);
// Make sure that notifications are not repeated.
$sink->clear();
$manualplugin->send_expiry_notifications($trace);
$this->assertEquals(0, $sink->count());
// use invalid notification hour to verify that before the hour the notifications are not sent.
$manualplugin->set_config('expirynotifylast', time() - 60*60*24);
$manualplugin->set_config('expirynotifyhour', '24');
$manualplugin->send_expiry_notifications($trace);
$this->assertEquals(0, $sink->count());
$manualplugin->set_config('expirynotifyhour', '0');
$manualplugin->send_expiry_notifications($trace);
$this->assertEquals(6, $sink->count());
}
/**
* Test for getting user enrolment actions.
*/
public function test_get_user_enrolment_actions(): void {
global $CFG, $PAGE;
$this->resetAfterTest();
// Set page URL to prevent debugging messages.
$PAGE->set_url('/enrol/editinstance.php');
$pluginname = 'manual';
// Only enable the manual enrol plugin.
$CFG->enrol_plugins_enabled = $pluginname;
$generator = $this->getDataGenerator();
// Get the enrol plugin.
$plugin = enrol_get_plugin($pluginname);
// Create a course.
$course = $generator->create_course();
// Enable this enrol plugin for the course.
$plugin->add_instance($course);
// Create a teacher.
$teacher = $generator->create_user();
// Enrol the teacher to the course.
$generator->enrol_user($teacher->id, $course->id, 'editingteacher', $pluginname);
// Create a student.
$student = $generator->create_user();
// Enrol the student to the course.
$generator->enrol_user($student->id, $course->id, 'student', $pluginname);
// Login as the teacher.
$this->setUser($teacher);
require_once($CFG->dirroot . '/enrol/locallib.php');
$manager = new course_enrolment_manager($PAGE, $course);
$userenrolments = $manager->get_user_enrolments($student->id);
$this->assertCount(1, $userenrolments);
$ue = reset($userenrolments);
$actions = $plugin->get_user_enrolment_actions($manager, $ue);
// Manual enrol has 2 enrol actions -- edit and unenrol.
$this->assertCount(2, $actions);
}
/**
* Test how the default enrolment instance inherits its settings from the global plugin settings.
*
* @dataProvider default_enrolment_instance_data_provider
* @param stdClass $expectation
* @param stdClass $globalsettings
* @covers \enrol_manual::add_default_instance
*/
public function test_default_enrolment_instance_acquires_correct_settings(stdClass $expectation, stdClass $globalsettings): void {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator();
// Given the plugin is globally configured with the following settings.
$plugin = enrol_get_plugin('manual');
$plugin->set_config('status', $globalsettings->status);
$plugin->set_config('roleid', $globalsettings->roleid);
$plugin->set_config('enrolperiod', $globalsettings->enrolperiod);
$plugin->set_config('expirynotify', $globalsettings->expirynotify);
$plugin->set_config('expirythreshold', $globalsettings->expirythreshold);
// When creating a course.
$course = $generator->create_course();
// Then the default manual enrolment instance being created is properly configured.
$enrolinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual']);
$this->assertEquals($expectation->status, $enrolinstance->status);
$this->assertEquals($expectation->roleid, $enrolinstance->roleid);
$this->assertEquals($expectation->enrolperiod, $enrolinstance->enrolperiod);
$this->assertEquals($expectation->expirynotify, $enrolinstance->expirynotify);
$this->assertEquals($expectation->notifyall, $enrolinstance->notifyall);
$this->assertEquals($expectation->expirythreshold, $enrolinstance->expirythreshold);
}
/**
* Data provider for test_default_enrolment_instance_acquires_correct_settings().
*
* @return array
*/
public function default_enrolment_instance_data_provider(): array {
$studentroles = get_archetype_roles('student');
$studentrole = array_shift($studentroles);
$teacherroles = get_archetype_roles('teacher');
$teacherrole = array_shift($teacherroles);
return [
'enabled, student role, no duration set, notify no one on expiry, 12 hours notification threshold' => [
'expectation' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 0,
'expirynotify' => 0,
'notifyall' => 0,
'expirythreshold' => 12 * HOURSECS,
],
'global settings' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 0,
'expirynotify' => 0,
'expirythreshold' => 12 * HOURSECS,
],
],
'enabled, student role, 72 hours duration, notify enroller only on expiry, 1 day notification threshold' => [
'expectation' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 72 * HOURSECS,
'expirynotify' => 1,
'notifyall' => 0,
'expirythreshold' => DAYSECS,
],
'global settings' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 72 * HOURSECS,
'expirynotify' => 1,
'expirythreshold' => DAYSECS,
],
],
'disabled, teacher role, no duration set, notify enroller and enrolled on expiry, 0 notification threshold' => [
'expectation' => (object) [
'status' => ENROL_INSTANCE_DISABLED,
'roleid' => $teacherrole->id,
'enrolperiod' => 0,
'expirynotify' => 2,
'notifyall' => 1,
'expirythreshold' => 0
],
'global settings' => (object) [
'status' => ENROL_INSTANCE_DISABLED,
'roleid' => $teacherrole->id,
'enrolperiod' => 0,
'expirynotify' => 2,
'expirythreshold' => 0,
],
],
];
}
/**
* Tests an enrolment instance is updated properly.
*
* @covers \enrol_manual::update_instance
* @dataProvider update_enrolment_instance_data_provider
*
* @param stdClass $expectation
* @param stdClass $updatedata
*/
public function test_enrolment_instance_is_updated(stdClass $expectation, stdClass $updatedata): void {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator();
$studentroles = get_archetype_roles('student');
$studentrole = array_shift($studentroles);
// Given the plugin is globally configured with the following settings.
$plugin = enrol_get_plugin('manual');
$plugin->set_config('status', ENROL_INSTANCE_ENABLED);
$plugin->set_config('roleid', $studentrole->id);
$plugin->set_config('enrolperiod', 30 * DAYSECS);
$plugin->set_config('expirynotify', 1);
$plugin->set_config('expirythreshold', 2 * DAYSECS);
// And a course is created with the default enrolment instance.
$course = $generator->create_course();
// When the enrolment instance is being updated.
$enrolinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual']);
$successfullyupdated = $plugin->update_instance($enrolinstance, $updatedata);
// Then the update is successful.
$this->assertTrue($successfullyupdated);
// And the updated enrolment instance contains the expected values.
$enrolinstance = $DB->get_record('enrol', ['id' => $enrolinstance->id]);
$this->assertEquals($expectation->status, $enrolinstance->status);
$this->assertEquals($expectation->roleid, $enrolinstance->roleid);
$this->assertEquals($expectation->enrolperiod, $enrolinstance->enrolperiod);
$this->assertEquals($expectation->expirynotify, $enrolinstance->expirynotify);
$this->assertEquals($expectation->notifyall, $enrolinstance->notifyall);
$this->assertEquals($expectation->expirythreshold, $enrolinstance->expirythreshold);
}
/**
* Data provider for test_enrolment_instance_is_updated().
*
* @return array
*/
public function update_enrolment_instance_data_provider(): array {
$studentroles = get_archetype_roles('student');
$studentrole = array_shift($studentroles);
$teacherroles = get_archetype_roles('teacher');
$teacherrole = array_shift($teacherroles);
return [
'disabled, all the others are default' => [
'expectation' => (object) [
'status' => ENROL_INSTANCE_DISABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 30 * DAYSECS,
'expirynotify' => 1,
'notifyall' => 0,
'expirythreshold' => 2 * DAYSECS,
],
'update data' => (object) [
'status' => ENROL_INSTANCE_DISABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 30 * DAYSECS,
'expirynotify' => 1,
'expirythreshold' => 2 * DAYSECS,
],
],
'enabled, teacher role, no duration set, notify no one on expiry, 0 notification threshold' => [
'expectation' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $teacherrole->id,
'enrolperiod' => 0,
'expirynotify' => 0,
'notifyall' => 0,
'expirythreshold' => 0,
],
'update data' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $teacherrole->id,
'enrolperiod' => 0,
'expirynotify' => 0,
'expirythreshold' => 0,
],
],
'notify enroller and enrolled on expiry, all the others are default' => [
'expectation' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 30 * DAYSECS,
'expirynotify' => 2,
'notifyall' => 1,
'expirythreshold' => 2 * DAYSECS,
],
'update data' => (object) [
'status' => ENROL_INSTANCE_ENABLED,
'roleid' => $studentrole->id,
'enrolperiod' => 30 * DAYSECS,
'expirynotify' => 2,
'expirythreshold' => 2 * DAYSECS,
],
],
];
}
/**
* Test the behaviour of find_instance().
*
* @covers ::find_instance
*/
public function test_find_instance(): void {
global $DB;
$this->resetAfterTest();
$cat = $this->getDataGenerator()->create_category();
// When we create a course, a manual enrolment instance is also created.
$course = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'ANON']);
$teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
$manualplugin = enrol_get_plugin('manual');
$expected = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual']);
// Let's try to add second instance - only 1 manual instance is possible.
$instanceid2 = $manualplugin->add_instance($course, ['roleid' => $teacherrole->id]);
$this->assertNull($instanceid2);
$enrolmentdata = [];
$actual = $manualplugin->find_instance($enrolmentdata, $course->id);
$this->assertEquals($expected->id, $actual->id);
}
/**
* Test send_course_welcome_message_to_user() method.
*
* @covers \enrol_plugin::send_course_welcome_message_to_user
*/
public function test_send_course_welcome_message(): void {
global $DB;
$this->resetAfterTest();
// Create course.
$course = $this->getDataGenerator()->create_course([
'fullname' => 'Course 1 & 2',
'shortname' => 'C1',
]);
// Create users.
$student = $this->getDataGenerator()->create_user();
$teacher1 = $this->getDataGenerator()->create_user();
$teacher2 = $this->getDataGenerator()->create_user();
$noreplyuser = \core_user::get_noreply_user();
// Enrol users.
$this->getDataGenerator()->enrol_user($teacher1->id, $course->id, 'editingteacher');
$this->getDataGenerator()->enrol_user($teacher2->id, $course->id, 'editingteacher');
// Get manual plugin.
$manualplugin = enrol_get_plugin('manual');
$maninstance = $DB->get_record(
'enrol',
['courseid' => $course->id, 'enrol' => 'manual'],
'*',
MUST_EXIST,
);
// Test 1: Send welcome message to user from course contact with default message.
// Redirect messages.
$messagesink = $this->redirectMessages();
$manualplugin->send_course_welcome_message_to_user(
instance: $maninstance,
userid: $student->id,
sendoption: ENROL_SEND_EMAIL_FROM_COURSE_CONTACT,
message: '',
);
$messages = $messagesink->get_messages_by_component_and_type(
'moodle',
'enrolcoursewelcomemessage',
);
$this->assertNotEmpty($messages);
$message = reset($messages);
// The message should be sent from the first teacher.
$this->assertEquals($teacher1->id, $message->useridfrom);
$this->assertStringContainsString($course->fullname, $message->subject);
$this->assertEquals(
get_string(
'customwelcomemessageplaceholder',
'core_enrol',
['fullname' => fullname($student), 'coursename' => $course->fullname],
),
$message->fullmessage,
);
// Clear sink.
$messagesink->clear();
// Test 2: Send welcome message to user from course contact with a custom message.
// Unenrol the first teacher from course.
$manualplugin->unenrol_user($maninstance, $teacher1->id);
// Redirect messages.
$messagesink = $this->redirectMessages();
$manualplugin->send_course_welcome_message_to_user(
instance: $maninstance,
userid: $student->id,
sendoption: ENROL_SEND_EMAIL_FROM_COURSE_CONTACT,
message: 'Your email address: {$a->email}, your first name: {$a->firstname}, your last name: {$a->lastname}, ' .
'your course: {$a->coursename}',
);
$messages = $messagesink->get_messages_by_component_and_type(
'moodle',
'enrolcoursewelcomemessage',
);
$this->assertNotEmpty($messages);
$message = reset($messages);
// The message should be sent from the second teacher.
$this->assertEquals($teacher2->id, $message->useridfrom);
$this->assertStringContainsString($course->fullname, $message->subject);
$this->assertEquals(
'Your email address: ' . $student->email . ', your first name: ' . $student->firstname . ', your last name: ' .
$student->lastname . ', your course: ' . $course->fullname,
$message->fullmessage,
);
// Clear sink.
$messagesink->clear();
// Test 3: Send welcome message to user from no-reply user with a custom message.
// Redirect messages.
$messagesink = $this->redirectMessages();
$manualplugin->send_course_welcome_message_to_user(
instance: $maninstance,
userid: $student->id,
sendoption: ENROL_SEND_EMAIL_FROM_NOREPLY,
message: 'Your email address: {$a->email}, your first name: {$a->firstname}, your last name: {$a->lastname}',
);
$messages = $messagesink->get_messages_by_component_and_type(
'moodle',
'enrolcoursewelcomemessage',
);
$this->assertNotEmpty($messages);
$message = reset($messages);
// The message should be sent from the noreply user.
$this->assertEquals($noreplyuser->id, $message->useridfrom);
$this->assertStringContainsString($course->fullname, $message->subject);
$this->assertEquals(
'Your email address: ' . $student->email . ', your first name: ' . $student->firstname . ', your last name: ' .
$student->lastname,
$message->fullmessage,
);
// Clear sink.
$messagesink->clear();
}
/**
* Test send_course_welcome_message_to_user() method via hook.
*
* @covers \enrol_plugin::send_course_welcome_message_to_user
*/
public function test_send_course_welcome_message_via_hook(): void {
global $DB;
$this->resetAfterTest();
$messagesink = $this->redirectMessages();
$course = $this->getDataGenerator()->create_course([
'fullname' => 'Course 1',
'shortname' => 'C1',
]);
$maninstance = $DB->get_record(
'enrol',
['courseid' => $course->id, 'enrol' => 'manual'],
'*',
MUST_EXIST,
);
$maninstance->customint1 = ENROL_SEND_EMAIL_FROM_NOREPLY;
$DB->update_record('enrol', $maninstance);
$student = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($student->id, $course->id);
$messages = $messagesink->get_messages_by_component_and_type(
'moodle',
'enrolcoursewelcomemessage',
);
$this->assertNotEmpty($messages);
$message = reset($messages);
$this->assertStringContainsString($course->fullname, $message->subject);
}
}