2012-03-31 23:51:02 +02:00
< ? 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/>.
/**
2013-07-27 10:58:11 +02:00
* Full functional accesslib test .
2012-03-31 23:51:02 +02:00
*
* @ package core
* @ category phpunit
* @ copyright 2011 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
defined ( 'MOODLE_INTERNAL' ) || die ();
/**
* Functional test for accesslib . php
*
* Note : execution may take many minutes especially on slower servers .
*/
2013-07-27 10:58:11 +02:00
class core_accesslib_testcase extends advanced_testcase {
2012-03-31 23:51:02 +02:00
/**
2013-07-27 10:58:11 +02:00
* Verify comparison of context instances in phpunit asserts .
2012-03-31 23:51:02 +02:00
*/
public function test_context_comparisons () {
$frontpagecontext1 = context_course :: instance ( SITEID );
context_helper :: reset_caches ();
$frontpagecontext2 = context_course :: instance ( SITEID );
$this -> assertEquals ( $frontpagecontext1 , $frontpagecontext2 );
$user1 = context_user :: instance ( 1 );
$user2 = context_user :: instance ( 2 );
$this -> assertNotEquals ( $user1 , $user2 );
}
/**
2012-05-16 17:24:17 +02:00
* Test resetting works .
*/
public function test_accesslib_clear_all_caches () {
global $ACCESSLIB_PRIVATE ;
$this -> resetAfterTest ();
$this -> setAdminUser ();
load_all_capabilities ();
$this -> assertNotEmpty ( $ACCESSLIB_PRIVATE -> accessdatabyuser );
2014-01-24 10:32:21 +11:00
accesslib_clear_all_caches_for_unit_testing ();
2012-05-16 17:24:17 +02:00
$this -> assertEmpty ( $ACCESSLIB_PRIVATE -> dirtycontexts );
$this -> assertEmpty ( $ACCESSLIB_PRIVATE -> accessdatabyuser );
}
2015-03-17 12:43:30 +10:30
/**
* Check modifying capability record is not exposed to other code .
*/
public function test_capabilities_mutation () {
$oldcap = get_capability_info ( 'moodle/site:config' );
$cap = get_capability_info ( 'moodle/site:config' );
unset ( $cap -> name );
$newcap = get_capability_info ( 'moodle/site:config' );
$this -> assertFalse ( isset ( $cap -> name ));
$this -> assertTrue ( isset ( $newcap -> name ));
$this -> assertTrue ( isset ( $oldcap -> name ));
}
2012-05-16 17:24:17 +02:00
/**
* Test getting of role access
*/
public function test_get_role_access () {
global $DB ;
$roles = $DB -> get_records ( 'role' );
foreach ( $roles as $role ) {
$access = get_role_access ( $role -> id );
$this -> assertTrue ( is_array ( $access ));
$this -> assertTrue ( is_array ( $access [ 'ra' ]));
2016-05-14 21:14:31 +09:30
$this -> assertFalse ( isset ( $access [ 'rdef' ]));
$this -> assertFalse ( isset ( $access [ 'rdef_count' ]));
$this -> assertFalse ( isset ( $access [ 'loaded' ]));
2012-05-16 17:24:17 +02:00
$this -> assertTrue ( isset ( $access [ 'time' ]));
$this -> assertTrue ( is_array ( $access [ 'rsw' ]));
}
// Note: the data is validated in the functional permission evaluation test at the end of this testcase.
}
/**
* Test getting of guest role .
*/
public function test_get_guest_role () {
global $CFG ;
$guest = get_guest_role ();
$this -> assertEquals ( 'guest' , $guest -> archetype );
$this -> assertEquals ( 'guest' , $guest -> shortname );
$this -> assertEquals ( $CFG -> guestroleid , $guest -> id );
}
/**
* Test if user is admin .
*/
public function test_is_siteadmin () {
2013-05-01 18:44:55 +01:00
global $DB , $CFG ;
2012-05-16 17:24:17 +02:00
$this -> resetAfterTest ();
$users = $DB -> get_records ( 'user' );
foreach ( $users as $user ) {
$this -> setUser ( 0 );
if ( $user -> username === 'admin' ) {
$this -> assertTrue ( is_siteadmin ( $user ));
$this -> assertTrue ( is_siteadmin ( $user -> id ));
$this -> setUser ( $user );
$this -> assertTrue ( is_siteadmin ());
$this -> assertTrue ( is_siteadmin ( null ));
} else {
$this -> assertFalse ( is_siteadmin ( $user ));
$this -> assertFalse ( is_siteadmin ( $user -> id ));
$this -> setUser ( $user );
$this -> assertFalse ( is_siteadmin ());
$this -> assertFalse ( is_siteadmin ( null ));
}
}
2013-05-01 18:44:55 +01:00
// Change the site admin list and check that it still works with
// multiple admins. We do this with userids only (not real user
// accounts) because it makes the test simpler.
$before = $CFG -> siteadmins ;
set_config ( 'siteadmins' , '666,667,668' );
$this -> assertTrue ( is_siteadmin ( 666 ));
$this -> assertTrue ( is_siteadmin ( 667 ));
$this -> assertTrue ( is_siteadmin ( 668 ));
$this -> assertFalse ( is_siteadmin ( 669 ));
set_config ( 'siteadmins' , '13' );
$this -> assertTrue ( is_siteadmin ( 13 ));
$this -> assertFalse ( is_siteadmin ( 666 ));
set_config ( 'siteadmins' , $before );
2012-05-16 17:24:17 +02:00
}
2012-06-20 20:16:13 +01:00
/**
* Test if user is enrolled in a course
*/
public function test_is_enrolled () {
global $DB ;
2013-07-27 10:58:11 +02:00
$this -> resetAfterTest ();
// Generate data.
2012-06-20 20:16:13 +01:00
$user = $this -> getDataGenerator () -> create_user ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$role = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ));
2013-07-27 10:58:11 +02:00
// There should be a manual enrolment as part of the default install.
2012-06-20 20:16:13 +01:00
$plugin = enrol_get_plugin ( 'manual' );
$instance = $DB -> get_record ( 'enrol' , array (
'courseid' => $course -> id ,
'enrol' => 'manual' ,
));
2013-07-27 10:58:11 +02:00
$this -> assertNotSame ( false , $instance );
2012-06-20 20:16:13 +01:00
2013-07-27 10:58:11 +02:00
// Enrol the user in the course.
2012-06-20 20:16:13 +01:00
$plugin -> enrol_user ( $instance , $user -> id , $role -> id );
2013-07-27 10:58:11 +02:00
// We'll test with the mod/assign:submit capability.
2012-06-20 20:16:13 +01:00
$capability = 'mod/assign:submit' ;
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => $capability )));
2013-07-27 10:58:11 +02:00
// Switch to our user.
2012-06-20 20:16:13 +01:00
$this -> setUser ( $user );
2013-07-27 10:58:11 +02:00
// Ensure that the user has the capability first.
2012-06-20 20:16:13 +01:00
$this -> assertTrue ( has_capability ( $capability , $coursecontext , $user -> id ));
// We first test whether the user is enrolled on the course as this
2013-07-27 10:58:11 +02:00
// seeds the cache, then we test for the capability.
2012-06-20 20:16:13 +01:00
$this -> assertTrue ( is_enrolled ( $coursecontext , $user , '' , true ));
$this -> assertTrue ( is_enrolled ( $coursecontext , $user , $capability ));
2013-07-27 10:58:11 +02:00
// Prevent the capability for this user role.
2012-06-20 20:16:13 +01:00
assign_capability ( $capability , CAP_PROHIBIT , $role -> id , $coursecontext );
$this -> assertFalse ( has_capability ( $capability , $coursecontext , $user -> id ));
// Again, we seed the cache first by checking initial enrolment,
2013-07-27 10:58:11 +02:00
// and then we test the actual capability.
2012-06-20 20:16:13 +01:00
$this -> assertTrue ( is_enrolled ( $coursecontext , $user , '' , true ));
$this -> assertFalse ( is_enrolled ( $coursecontext , $user , $capability ));
}
2012-05-16 17:24:17 +02:00
/**
* Test logged in test .
*/
public function test_isloggedin () {
global $USER ;
$this -> resetAfterTest ();
$USER -> id = 0 ;
$this -> assertFalse ( isloggedin ());
$USER -> id = 1 ;
$this -> assertTrue ( isloggedin ());
}
/**
* Test guest user test .
*/
public function test_isguestuser () {
global $DB ;
$this -> resetAfterTest ();
$guest = $DB -> get_record ( 'user' , array ( 'username' => 'guest' ));
$this -> setUser ( 0 );
$this -> assertFalse ( isguestuser ());
$this -> setAdminUser ();
$this -> assertFalse ( isguestuser ());
$this -> assertTrue ( isguestuser ( $guest ));
$this -> assertTrue ( isguestuser ( $guest -> id ));
$this -> setUser ( $guest );
$this -> assertTrue ( isguestuser ());
$users = $DB -> get_records ( 'user' );
foreach ( $users as $user ) {
if ( $user -> username === 'guest' ) {
continue ;
}
$this -> assertFalse ( isguestuser ( $user ));
}
}
/**
* Test capability riskiness .
*/
public function test_is_safe_capability () {
global $DB ;
// Note: there is not much to test, just make sure no notices are throw for the most dangerous cap.
$capability = $DB -> get_record ( 'capabilities' , array ( 'name' => 'moodle/site:config' ), '*' , MUST_EXIST );
$this -> assertFalse ( is_safe_capability ( $capability ));
}
/**
* Test context fetching .
*/
public function test_get_context_info_array () {
$this -> resetAfterTest ();
$syscontext = context_system :: instance ();
$user = $this -> getDataGenerator () -> create_user ();
$usercontext = context_user :: instance ( $user -> id );
$course = $this -> getDataGenerator () -> create_course ();
$catcontext = context_coursecat :: instance ( $course -> category );
$coursecontext = context_course :: instance ( $course -> id );
$page = $this -> getDataGenerator () -> create_module ( 'page' , array ( 'course' => $course -> id ));
$modcontext = context_module :: instance ( $page -> cmid );
$cm = get_coursemodule_from_instance ( 'page' , $page -> id );
$block1 = $this -> getDataGenerator () -> create_block ( 'online_users' , array ( 'parentcontextid' => $coursecontext -> id ));
$block1context = context_block :: instance ( $block1 -> id );
$block2 = $this -> getDataGenerator () -> create_block ( 'online_users' , array ( 'parentcontextid' => $modcontext -> id ));
$block2context = context_block :: instance ( $block2 -> id );
$result = get_context_info_array ( $syscontext -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $syscontext , $result [ 0 ]);
$this -> assertNull ( $result [ 1 ]);
$this -> assertNull ( $result [ 2 ]);
2012-05-16 17:24:17 +02:00
$result = get_context_info_array ( $usercontext -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $usercontext , $result [ 0 ]);
$this -> assertNull ( $result [ 1 ]);
$this -> assertNull ( $result [ 2 ]);
2012-05-16 17:24:17 +02:00
$result = get_context_info_array ( $catcontext -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $catcontext , $result [ 0 ]);
$this -> assertNull ( $result [ 1 ]);
$this -> assertNull ( $result [ 2 ]);
2012-05-16 17:24:17 +02:00
$result = get_context_info_array ( $coursecontext -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $coursecontext , $result [ 0 ]);
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $course -> id , $result [ 1 ] -> id );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $course -> shortname , $result [ 1 ] -> shortname );
$this -> assertNull ( $result [ 2 ]);
2012-05-16 17:24:17 +02:00
$result = get_context_info_array ( $block1context -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $block1context , $result [ 0 ]);
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $course -> id , $result [ 1 ] -> id );
$this -> assertEquals ( $course -> shortname , $result [ 1 ] -> shortname );
2013-07-27 10:58:11 +02:00
$this -> assertNull ( $result [ 2 ]);
2012-05-16 17:24:17 +02:00
$result = get_context_info_array ( $modcontext -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $modcontext , $result [ 0 ]);
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $course -> id , $result [ 1 ] -> id );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $course -> shortname , $result [ 1 ] -> shortname );
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $cm -> id , $result [ 2 ] -> id );
$result = get_context_info_array ( $block2context -> id );
$this -> assertCount ( 3 , $result );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $block2context , $result [ 0 ]);
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $course -> id , $result [ 1 ] -> id );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $course -> shortname , $result [ 1 ] -> shortname );
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $cm -> id , $result [ 2 ] -> id );
}
/**
* Test looking for course contacts .
*/
public function test_has_coursecontact_role () {
global $DB , $CFG ;
$this -> resetAfterTest ();
$users = $DB -> get_records ( 'user' );
// Nobody is expected to have any course level roles.
$this -> assertNotEmpty ( $CFG -> coursecontact );
2013-07-27 10:58:11 +02:00
foreach ( $users as $user ) {
2012-05-16 17:24:17 +02:00
$this -> assertFalse ( has_coursecontact_role ( $user -> id ));
}
$user = $this -> getDataGenerator () -> create_user ();
$course = $this -> getDataGenerator () -> create_course ();
role_assign ( $CFG -> coursecontact , $user -> id , context_course :: instance ( $course -> id ));
$this -> assertTrue ( has_coursecontact_role ( $user -> id ));
}
/**
* Test creation of roles .
*/
public function test_create_role () {
global $DB ;
$this -> resetAfterTest ();
$id = create_role ( 'New student role' , 'student2' , 'New student description' , 'student' );
$role = $DB -> get_record ( 'role' , array ( 'id' => $id ));
$this -> assertNotEmpty ( $role );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( 'New student role' , $role -> name );
$this -> assertSame ( 'student2' , $role -> shortname );
$this -> assertSame ( 'New student description' , $role -> description );
$this -> assertSame ( 'student' , $role -> archetype );
2012-05-16 17:24:17 +02:00
}
/**
* Test adding of capabilities to roles .
*/
public function test_assign_capability () {
global $DB ;
$this -> resetAfterTest ();
$user = $this -> getDataGenerator () -> create_user ();
$syscontext = context_system :: instance ();
$frontcontext = context_course :: instance ( SITEID );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
2013-07-27 10:58:11 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' ))); // Any capability assigned to student by default.
2012-05-16 17:24:17 +02:00
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $syscontext -> id , 'roleid' => $student -> id , 'capability' => 'moodle/backup:backupcourse' )));
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $student -> id , 'capability' => 'moodle/backup:backupcourse' )));
$this -> setUser ( $user );
$result = assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $student -> id , $frontcontext -> id );
$this -> assertTrue ( $result );
$permission = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $student -> id , 'capability' => 'moodle/backup:backupcourse' ));
$this -> assertNotEmpty ( $permission );
$this -> assertEquals ( CAP_ALLOW , $permission -> permission );
$this -> assertEquals ( $user -> id , $permission -> modifierid );
$this -> setUser ( 0 );
$result = assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $student -> id , $frontcontext -> id , false );
$this -> assertTrue ( $result );
$permission = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $student -> id , 'capability' => 'moodle/backup:backupcourse' ));
$this -> assertNotEmpty ( $permission );
$this -> assertEquals ( CAP_ALLOW , $permission -> permission );
2014-02-16 13:11:27 +11:00
$this -> assertEquals ( $user -> id , $permission -> modifierid );
2012-05-16 17:24:17 +02:00
$result = assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $student -> id , $frontcontext -> id , true );
$this -> assertTrue ( $result );
$permission = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $student -> id , 'capability' => 'moodle/backup:backupcourse' ));
$this -> assertNotEmpty ( $permission );
$this -> assertEquals ( CAP_PROHIBIT , $permission -> permission );
$this -> assertEquals ( 0 , $permission -> modifierid );
$result = assign_capability ( 'moodle/backup:backupcourse' , CAP_INHERIT , $student -> id , $frontcontext -> id );
$this -> assertTrue ( $result );
$permission = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $student -> id , 'capability' => 'moodle/backup:backupcourse' ));
$this -> assertEmpty ( $permission );
2013-08-07 10:23:39 +08:00
// Test event trigger.
$rolecapabilityevent = \core\event\role_capabilities_updated :: create ( array ( 'context' => $syscontext ,
'objectid' => $student -> id ,
'other' => array ( 'name' => $student -> shortname )
));
$expectedlegacylog = array ( SITEID , 'role' , 'view' , 'admin/roles/define.php?action=view&roleid=' . $student -> id ,
$student -> shortname , '' , $user -> id );
$rolecapabilityevent -> set_legacy_logdata ( $expectedlegacylog );
$rolecapabilityevent -> add_record_snapshot ( 'role' , $student );
$sink = $this -> redirectEvents ();
$rolecapabilityevent -> trigger ();
$events = $sink -> get_events ();
$sink -> close ();
$event = array_pop ( $events );
$this -> assertInstanceOf ( '\core\event\role_capabilities_updated' , $event );
2014-04-01 14:51:05 +08:00
$expectedurl = new moodle_url ( '/admin/roles/define.php' , array ( 'action' => 'view' , 'roleid' => $student -> id ));
2013-08-07 10:23:39 +08:00
$this -> assertEquals ( $expectedurl , $event -> get_url ());
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2014-04-01 14:51:05 +08:00
$this -> assertEventContextNotUsed ( $event );
2012-05-16 17:24:17 +02:00
}
/**
* Test removing of capabilities from roles .
*/
public function test_unassign_capability () {
global $DB ;
$this -> resetAfterTest ();
$syscontext = context_system :: instance ();
$frontcontext = context_course :: instance ( SITEID );
$manager = $DB -> get_record ( 'role' , array ( 'shortname' => 'manager' ), '*' , MUST_EXIST );
2013-07-27 10:58:11 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' ))); // Any capability assigned to manager by default.
2012-05-16 17:24:17 +02:00
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $manager -> id , $frontcontext -> id );
$this -> assertTrue ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $syscontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
$this -> assertTrue ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
$result = unassign_capability ( 'moodle/backup:backupcourse' , $manager -> id , $syscontext -> id );
$this -> assertTrue ( $result );
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $syscontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
$this -> assertTrue ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
unassign_capability ( 'moodle/backup:backupcourse' , $manager -> id , $frontcontext );
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $manager -> id , $syscontext -> id );
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $manager -> id , $frontcontext -> id );
$this -> assertTrue ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
$result = unassign_capability ( 'moodle/backup:backupcourse' , $manager -> id );
$this -> assertTrue ( $result );
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $syscontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'contextid' => $frontcontext -> id , 'roleid' => $manager -> id , 'capability' => 'moodle/backup:backupcourse' )));
}
/**
2013-07-27 10:58:11 +02:00
* Test role assigning .
2012-05-16 17:24:17 +02:00
*/
public function test_role_assign () {
global $DB , $USER ;
$this -> resetAfterTest ();
$user = $this -> getDataGenerator () -> create_user ();
$course = $this -> getDataGenerator () -> create_course ();
$role = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ));
$this -> setUser ( 0 );
$context = context_system :: instance ();
$this -> assertFalse ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id )));
role_assign ( $role -> id , $user -> id , $context -> id );
$ras = $DB -> get_record ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id ));
$this -> assertNotEmpty ( $ras );
$this -> assertSame ( '' , $ras -> component );
$this -> assertSame ( '0' , $ras -> itemid );
$this -> assertEquals ( $USER -> id , $ras -> modifierid );
$this -> setAdminUser ();
$context = context_course :: instance ( $course -> id );
$this -> assertFalse ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id )));
role_assign ( $role -> id , $user -> id , $context -> id , 'enrol_self' , 1 , 666 );
$ras = $DB -> get_record ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id ));
$this -> assertNotEmpty ( $ras );
$this -> assertSame ( 'enrol_self' , $ras -> component );
$this -> assertSame ( '1' , $ras -> itemid );
$this -> assertEquals ( $USER -> id , $ras -> modifierid );
$this -> assertEquals ( 666 , $ras -> timemodified );
2013-07-14 13:25:36 +02:00
// Test event triggered.
$user2 = $this -> getDataGenerator () -> create_user ();
$sink = $this -> redirectEvents ();
$raid = role_assign ( $role -> id , $user2 -> id , $context -> id );
$events = $sink -> get_events ();
$sink -> close ();
$this -> assertCount ( 1 , $events );
$event = $events [ 0 ];
$this -> assertInstanceOf ( '\core\event\role_assigned' , $event );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( 'role' , $event -> target );
$this -> assertSame ( 'role' , $event -> objecttable );
2013-07-14 13:25:36 +02:00
$this -> assertEquals ( $role -> id , $event -> objectid );
$this -> assertEquals ( $context -> id , $event -> contextid );
$this -> assertEquals ( $user2 -> id , $event -> relateduserid );
$this -> assertCount ( 3 , $event -> other );
$this -> assertEquals ( $raid , $event -> other [ 'id' ]);
$this -> assertSame ( '' , $event -> other [ 'component' ]);
$this -> assertEquals ( 0 , $event -> other [ 'itemid' ]);
2013-10-27 10:22:44 +01:00
$this -> assertInstanceOf ( 'moodle_url' , $event -> get_url ());
2013-08-06 13:56:11 +08:00
$this -> assertSame ( 'role_assigned' , $event :: get_legacy_eventname ());
2013-08-08 11:42:13 +08:00
$roles = get_all_roles ();
$rolenames = role_fix_names ( $roles , $context , ROLENAME_ORIGINAL , true );
$expectedlegacylog = array ( $course -> id , 'role' , 'assign' ,
'admin/roles/assign.php?contextid=' . $context -> id . '&roleid=' . $role -> id , $rolenames [ $role -> id ], '' , $USER -> id );
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2012-05-16 17:24:17 +02:00
}
/**
2013-07-27 10:58:11 +02:00
* Test role unassigning .
2012-05-16 17:24:17 +02:00
*/
public function test_role_unassign () {
2013-08-08 11:42:13 +08:00
global $DB , $USER ;
2012-05-16 17:24:17 +02:00
$this -> resetAfterTest ();
$user = $this -> getDataGenerator () -> create_user ();
$course = $this -> getDataGenerator () -> create_course ();
$role = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ));
2013-07-14 13:25:36 +02:00
$context = context_course :: instance ( $course -> id );
2012-05-16 17:24:17 +02:00
role_assign ( $role -> id , $user -> id , $context -> id );
$this -> assertTrue ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id )));
role_unassign ( $role -> id , $user -> id , $context -> id );
$this -> assertFalse ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id )));
role_assign ( $role -> id , $user -> id , $context -> id , 'enrol_self' , 1 );
$this -> assertTrue ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id )));
role_unassign ( $role -> id , $user -> id , $context -> id , 'enrol_self' , 1 );
$this -> assertFalse ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $user -> id , 'roleid' => $role -> id , 'contextid' => $context -> id )));
2013-07-14 13:25:36 +02:00
// Test event triggered.
role_assign ( $role -> id , $user -> id , $context -> id );
$sink = $this -> redirectEvents ();
role_unassign ( $role -> id , $user -> id , $context -> id );
$events = $sink -> get_events ();
$sink -> close ();
$this -> assertCount ( 1 , $events );
$event = $events [ 0 ];
$this -> assertInstanceOf ( '\core\event\role_unassigned' , $event );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( 'role' , $event -> target );
$this -> assertSame ( 'role' , $event -> objecttable );
2013-07-14 13:25:36 +02:00
$this -> assertEquals ( $role -> id , $event -> objectid );
$this -> assertEquals ( $context -> id , $event -> contextid );
$this -> assertEquals ( $user -> id , $event -> relateduserid );
$this -> assertCount ( 3 , $event -> other );
$this -> assertSame ( '' , $event -> other [ 'component' ]);
$this -> assertEquals ( 0 , $event -> other [ 'itemid' ]);
2013-10-27 10:22:44 +01:00
$this -> assertInstanceOf ( 'moodle_url' , $event -> get_url ());
2013-08-08 11:42:13 +08:00
$roles = get_all_roles ();
$rolenames = role_fix_names ( $roles , $context , ROLENAME_ORIGINAL , true );
$expectedlegacylog = array ( $course -> id , 'role' , 'unassign' ,
'admin/roles/assign.php?contextid=' . $context -> id . '&roleid=' . $role -> id , $rolenames [ $role -> id ], '' , $USER -> id );
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2012-05-16 17:24:17 +02:00
}
/**
2013-07-27 10:58:11 +02:00
* Test role unassigning .
2012-05-16 17:24:17 +02:00
*/
public function test_role_unassign_all () {
global $DB ;
$this -> resetAfterTest ();
$user = $this -> getDataGenerator () -> create_user ();
$course = $this -> getDataGenerator () -> create_course ();
$role = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ));
2013-07-14 13:25:36 +02:00
$role2 = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ));
2012-05-16 17:24:17 +02:00
$syscontext = context_system :: instance ();
$coursecontext = context_course :: instance ( $course -> id );
$page = $this -> getDataGenerator () -> create_module ( 'page' , array ( 'course' => $course -> id ));
$modcontext = context_module :: instance ( $page -> cmid );
role_assign ( $role -> id , $user -> id , $syscontext -> id );
role_assign ( $role -> id , $user -> id , $coursecontext -> id , 'enrol_self' , 1 );
$this -> assertEquals ( 2 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_unassign_all ( array ( 'userid' => $user -> id , 'roleid' => $role -> id ));
$this -> assertEquals ( 0 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_assign ( $role -> id , $user -> id , $syscontext -> id );
role_assign ( $role -> id , $user -> id , $coursecontext -> id , 'enrol_self' , 1 );
role_assign ( $role -> id , $user -> id , $modcontext -> id );
$this -> assertEquals ( 3 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_unassign_all ( array ( 'userid' => $user -> id , 'contextid' => $coursecontext -> id ), false );
$this -> assertEquals ( 2 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_unassign_all ( array ( 'userid' => $user -> id , 'contextid' => $coursecontext -> id ), true );
$this -> assertEquals ( 1 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_unassign_all ( array ( 'userid' => $user -> id ));
$this -> assertEquals ( 0 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_assign ( $role -> id , $user -> id , $syscontext -> id );
role_assign ( $role -> id , $user -> id , $coursecontext -> id , 'enrol_self' , 1 );
role_assign ( $role -> id , $user -> id , $coursecontext -> id );
role_assign ( $role -> id , $user -> id , $modcontext -> id );
$this -> assertEquals ( 4 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
role_unassign_all ( array ( 'userid' => $user -> id , 'contextid' => $coursecontext -> id , 'component' => 'enrol_self' ), true , true );
$this -> assertEquals ( 1 , $DB -> count_records ( 'role_assignments' , array ( 'userid' => $user -> id )));
2013-07-14 13:25:36 +02:00
// Test events triggered.
role_assign ( $role2 -> id , $user -> id , $coursecontext -> id );
role_assign ( $role2 -> id , $user -> id , $modcontext -> id );
$sink = $this -> redirectEvents ();
role_unassign_all ( array ( 'userid' => $user -> id , 'roleid' => $role2 -> id ));
$events = $sink -> get_events ();
$sink -> close ();
$this -> assertCount ( 2 , $events );
$this -> assertInstanceOf ( '\core\event\role_unassigned' , $events [ 0 ]);
$this -> assertInstanceOf ( '\core\event\role_unassigned' , $events [ 1 ]);
2012-05-16 17:24:17 +02:00
}
/**
* Test role queries .
*/
public function test_get_roles_with_capability () {
global $DB ;
$this -> resetAfterTest ();
$syscontext = context_system :: instance ();
$frontcontext = context_course :: instance ( SITEID );
$manager = $DB -> get_record ( 'role' , array ( 'shortname' => 'manager' ), '*' , MUST_EXIST );
$teacher = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ), '*' , MUST_EXIST );
2013-07-27 10:58:11 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' ))); // Any capability is ok.
2012-05-16 17:24:17 +02:00
$DB -> delete_records ( 'role_capabilities' , array ( 'capability' => 'moodle/backup:backupcourse' ));
$roles = get_roles_with_capability ( 'moodle/backup:backupcourse' );
$this -> assertEquals ( array (), $roles );
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $manager -> id , $syscontext -> id );
assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $manager -> id , $frontcontext -> id );
assign_capability ( 'moodle/backup:backupcourse' , CAP_PREVENT , $teacher -> id , $frontcontext -> id );
$roles = get_roles_with_capability ( 'moodle/backup:backupcourse' );
$this -> assertEquals ( array ( $teacher -> id , $manager -> id ), array_keys ( $roles ), '' , 0 , 10 , true );
$roles = get_roles_with_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW );
$this -> assertEquals ( array ( $manager -> id ), array_keys ( $roles ), '' , 0 , 10 , true );
2013-07-27 10:58:11 +02:00
$roles = get_roles_with_capability ( 'moodle/backup:backupcourse' , null , $syscontext );
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( array ( $manager -> id ), array_keys ( $roles ), '' , 0 , 10 , true );
}
/**
* Test deleting of roles .
*/
public function test_delete_role () {
global $DB ;
$this -> resetAfterTest ();
$role = $DB -> get_record ( 'role' , array ( 'shortname' => 'manager' ), '*' , MUST_EXIST );
$user = $this -> getDataGenerator () -> create_user ();
role_assign ( $role -> id , $user -> id , context_system :: instance ());
$course = $this -> getDataGenerator () -> create_course ();
$rolename = ( object ) array ( 'roleid' => $role -> id , 'name' => 'Man' , 'contextid' => context_course :: instance ( $course -> id ) -> id );
$DB -> insert_record ( 'role_names' , $rolename );
$this -> assertTrue ( $DB -> record_exists ( 'role_assignments' , array ( 'roleid' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_capabilities' , array ( 'roleid' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_names' , array ( 'roleid' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_context_levels' , array ( 'roleid' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_assign' , array ( 'roleid' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_assign' , array ( 'allowassign' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_override' , array ( 'roleid' => $role -> id )));
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_override' , array ( 'allowoverride' => $role -> id )));
2013-08-06 09:37:55 +08:00
// Delete role and get event.
$sink = $this -> redirectEvents ();
2012-05-16 17:24:17 +02:00
$result = delete_role ( $role -> id );
2013-08-06 09:37:55 +08:00
$events = $sink -> get_events ();
$sink -> close ();
$event = array_pop ( $events );
2012-05-16 17:24:17 +02:00
$this -> assertTrue ( $result );
$this -> assertFalse ( $DB -> record_exists ( 'role' , array ( 'id' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_assignments' , array ( 'roleid' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_capabilities' , array ( 'roleid' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_names' , array ( 'roleid' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_context_levels' , array ( 'roleid' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_assign' , array ( 'roleid' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_assign' , array ( 'allowassign' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_override' , array ( 'roleid' => $role -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_override' , array ( 'allowoverride' => $role -> id )));
2013-08-06 09:37:55 +08:00
// Test triggered event.
$this -> assertInstanceOf ( '\core\event\role_deleted' , $event );
$this -> assertSame ( 'role' , $event -> target );
$this -> assertSame ( 'role' , $event -> objecttable );
$this -> assertSame ( $role -> id , $event -> objectid );
$this -> assertEquals ( context_system :: instance (), $event -> get_context ());
$this -> assertSame ( $role -> shortname , $event -> other [ 'shortname' ]);
$this -> assertSame ( $role -> description , $event -> other [ 'description' ]);
$this -> assertSame ( $role -> archetype , $event -> other [ 'archetype' ]);
$expectedlegacylog = array ( SITEID , 'role' , 'delete' , 'admin/roles/manage.php?action=delete&roleid=' . $role -> id ,
$role -> shortname , '' );
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2012-05-16 17:24:17 +02:00
}
/**
* Test fetching of all roles .
*/
public function test_get_all_roles () {
2012-05-18 11:40:35 +02:00
global $DB ;
$this -> resetAfterTest ();
2012-05-16 17:24:17 +02:00
$allroles = get_all_roles ();
2019-05-27 17:45:58 +02:00
$this -> assertIsArray ( $allroles );
$initialrolescount = count ( $allroles );
$this -> assertTrue ( $initialrolescount >= 8 ); // There are 8 roles is standard install.
$rolenames = array_column ( $allroles , 'shortname' );
foreach ( get_role_archetypes () as $archetype ) {
$this -> assertContains ( $archetype , $rolenames );
}
2012-05-16 17:24:17 +02:00
$role = reset ( $allroles );
$role = ( array ) $role ;
$this -> assertEquals ( array ( 'id' , 'name' , 'shortname' , 'description' , 'sortorder' , 'archetype' ), array_keys ( $role ), '' , 0 , 10 , true );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $role ) {
2012-05-16 17:24:17 +02:00
$this -> assertEquals ( $role -> id , $roleid );
}
2012-05-18 11:40:35 +02:00
$teacher = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ), '*' , MUST_EXIST );
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$teacherename = ( object ) array ( 'roleid' => $teacher -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherename );
$otherrename = ( object ) array ( 'roleid' => $otherid , 'name' => 'Ostatní' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $otherrename );
2013-07-27 10:58:11 +02:00
$renames = $DB -> get_records_menu ( 'role_names' , array ( 'contextid' => $coursecontext -> id ), '' , 'roleid, name' );
2012-05-18 11:40:35 +02:00
$allroles = get_all_roles ( $coursecontext );
2019-05-27 17:45:58 +02:00
$this -> assertIsArray ( $allroles );
$this -> assertCount ( $initialrolescount + 1 , $allroles );
2012-05-18 11:40:35 +02:00
$role = reset ( $allroles );
$role = ( array ) $role ;
$this -> assertEquals ( array ( 'id' , 'name' , 'shortname' , 'description' , 'sortorder' , 'archetype' , 'coursealias' ), array_keys ( $role ), '' , 0 , 10 , true );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $role ) {
2012-05-18 11:40:35 +02:00
$this -> assertEquals ( $role -> id , $roleid );
if ( isset ( $renames [ $roleid ])) {
$this -> assertSame ( $renames [ $roleid ], $role -> coursealias );
} else {
2013-07-27 10:58:11 +02:00
$this -> assertNull ( $role -> coursealias );
2012-05-18 11:40:35 +02:00
}
}
2012-05-16 17:24:17 +02:00
}
/**
* Test getting of all archetypes .
*/
public function test_get_role_archetypes () {
$archetypes = get_role_archetypes ();
2013-07-27 10:58:11 +02:00
$this -> assertCount ( 8 , $archetypes ); // There are 8 archetypes in standard install.
foreach ( $archetypes as $k => $v ) {
2012-05-16 17:24:17 +02:00
$this -> assertSame ( $k , $v );
}
}
/**
* Test getting of roles with given archetype .
*/
public function test_get_archetype_roles () {
$this -> resetAfterTest ();
2019-05-27 17:45:58 +02:00
// New install should have at least 1 role for each archetype.
2012-05-16 17:24:17 +02:00
$archetypes = get_role_archetypes ();
foreach ( $archetypes as $archetype ) {
$roles = get_archetype_roles ( $archetype );
2019-05-27 17:45:58 +02:00
$this -> assertGreaterThanOrEqual ( 1 , count ( $roles ));
2012-05-16 17:24:17 +02:00
$role = reset ( $roles );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $archetype , $role -> archetype );
2012-05-16 17:24:17 +02:00
}
create_role ( 'New student role' , 'student2' , 'New student description' , 'student' );
$roles = get_archetype_roles ( 'student' );
$this -> assertCount ( 2 , $roles );
}
/**
2013-07-27 10:58:11 +02:00
* Test aliased role names .
2012-05-16 17:24:17 +02:00
*/
public function test_role_get_name () {
global $DB ;
$this -> resetAfterTest ();
$allroles = $DB -> get_records ( 'role' );
2012-05-18 11:40:35 +02:00
$teacher = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ), '*' , MUST_EXIST );
2012-05-16 17:24:17 +02:00
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
2012-05-18 11:40:35 +02:00
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
2012-05-16 17:24:17 +02:00
$teacherename = ( object ) array ( 'roleid' => $teacher -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherename );
2012-05-18 11:40:35 +02:00
$otherrename = ( object ) array ( 'roleid' => $otherid , 'name' => 'Ostatní' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $otherrename );
2013-07-27 10:58:11 +02:00
$renames = $DB -> get_records_menu ( 'role_names' , array ( 'contextid' => $coursecontext -> id ), '' , 'roleid, name' );
2012-05-16 17:24:17 +02:00
foreach ( $allroles as $role ) {
2019-05-27 17:45:58 +02:00
if ( in_array ( $role -> shortname , get_role_archetypes ())) {
// Standard roles do not have a set name.
$this -> assertSame ( '' , $role -> name );
}
2012-05-18 11:40:35 +02:00
// Get localised name from lang pack.
$name = role_get_name ( $role , null , ROLENAME_ORIGINAL );
$this -> assertNotEmpty ( $name );
$this -> assertNotEquals ( $role -> shortname , $name );
if ( isset ( $renames [ $role -> id ])) {
$this -> assertSame ( $renames [ $role -> id ], role_get_name ( $role , $coursecontext ));
$this -> assertSame ( $renames [ $role -> id ], role_get_name ( $role , $coursecontext , ROLENAME_ALIAS ));
$this -> assertSame ( $renames [ $role -> id ], role_get_name ( $role , $coursecontext , ROLENAME_ALIAS_RAW ));
$this -> assertSame ( " { $renames [ $role -> id ] } ( $name ) " , role_get_name ( $role , $coursecontext , ROLENAME_BOTH ));
} else {
$this -> assertSame ( $name , role_get_name ( $role , $coursecontext ));
$this -> assertSame ( $name , role_get_name ( $role , $coursecontext , ROLENAME_ALIAS ));
2013-07-27 10:58:11 +02:00
$this -> assertNull ( role_get_name ( $role , $coursecontext , ROLENAME_ALIAS_RAW ));
2012-05-18 11:40:35 +02:00
$this -> assertSame ( $name , role_get_name ( $role , $coursecontext , ROLENAME_BOTH ));
2012-05-16 17:24:17 +02:00
}
2012-05-18 11:40:35 +02:00
$this -> assertSame ( $name , role_get_name ( $role ));
$this -> assertSame ( $name , role_get_name ( $role , $coursecontext , ROLENAME_ORIGINAL ));
$this -> assertSame ( $name , role_get_name ( $role , null , ROLENAME_ORIGINAL ));
$this -> assertSame ( $role -> shortname , role_get_name ( $role , $coursecontext , ROLENAME_SHORT ));
$this -> assertSame ( $role -> shortname , role_get_name ( $role , null , ROLENAME_SHORT ));
$this -> assertSame ( " $name ( $role->shortname ) " , role_get_name ( $role , $coursecontext , ROLENAME_ORIGINALANDSHORT ));
$this -> assertSame ( " $name ( $role->shortname ) " , role_get_name ( $role , null , ROLENAME_ORIGINALANDSHORT ));
2013-07-27 10:58:11 +02:00
$this -> assertNull ( role_get_name ( $role , null , ROLENAME_ALIAS_RAW ));
2012-05-16 17:24:17 +02:00
}
}
/**
2013-07-27 10:58:11 +02:00
* Test tweaking of role name arrays .
2012-03-31 23:51:02 +02:00
*/
2012-05-16 17:24:17 +02:00
public function test_role_fix_names () {
global $DB ;
$this -> resetAfterTest ();
$teacher = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ), '*' , MUST_EXIST );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$anotherid = create_role ( 'Another role' , 'another' , 'Yet another other role' , '' );
$allroles = $DB -> get_records ( 'role' );
$syscontext = context_system :: instance ();
$frontcontext = context_course :: instance ( SITEID );
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$category = $DB -> get_record ( 'course_categories' , array ( 'id' => $course -> category ), '*' , MUST_EXIST );
$categorycontext = context_coursecat :: instance ( $category -> id );
$teacherename = ( object ) array ( 'roleid' => $teacher -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherename );
$otherrename = ( object ) array ( 'roleid' => $otherid , 'name' => 'Ostatní' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $otherrename );
2013-07-27 10:58:11 +02:00
$renames = $DB -> get_records_menu ( 'role_names' , array ( 'contextid' => $coursecontext -> id ), '' , 'roleid, name' );
2012-05-16 17:24:17 +02:00
// Make sure all localname contain proper values for each ROLENAME_ constant,
2013-07-27 10:58:11 +02:00
// note role_get_name() on frontpage is used to get the original name for future compatibility.
2012-05-16 17:24:17 +02:00
$roles = $allroles ;
2013-07-27 10:58:11 +02:00
unset ( $roles [ $student -> id ]); // Remove one role to make sure no role is added or removed.
2012-05-16 17:24:17 +02:00
$rolenames = array ();
foreach ( $roles as $role ) {
$rolenames [ $role -> id ] = $role -> name ;
}
2012-05-18 11:40:35 +02:00
$alltypes = array ( ROLENAME_ALIAS , ROLENAME_ALIAS_RAW , ROLENAME_BOTH , ROLENAME_ORIGINAL , ROLENAME_ORIGINALANDSHORT , ROLENAME_SHORT );
foreach ( $alltypes as $type ) {
$fixed = role_fix_names ( $roles , $coursecontext , $type );
$this -> assertCount ( count ( $roles ), $fixed );
2013-07-27 10:58:11 +02:00
foreach ( $fixed as $roleid => $rolename ) {
2012-05-18 11:40:35 +02:00
$this -> assertInstanceOf ( 'stdClass' , $rolename );
$role = $allroles [ $roleid ];
$name = role_get_name ( $role , $coursecontext , $type );
$this -> assertSame ( $name , $rolename -> localname );
2012-05-16 17:24:17 +02:00
}
2012-05-18 11:40:35 +02:00
$fixed = role_fix_names ( $rolenames , $coursecontext , $type );
$this -> assertCount ( count ( $rolenames ), $fixed );
2013-07-27 10:58:11 +02:00
foreach ( $fixed as $roleid => $rolename ) {
2012-05-18 11:40:35 +02:00
$role = $allroles [ $roleid ];
$name = role_get_name ( $role , $coursecontext , $type );
$this -> assertSame ( $name , $rolename );
2012-05-16 17:24:17 +02:00
}
}
}
2013-06-17 11:27:42 +02:00
/**
* Test role default allows .
*/
public function test_get_default_role_archetype_allows () {
$archetypes = get_role_archetypes ();
foreach ( $archetypes as $archetype ) {
$result = get_default_role_archetype_allows ( 'assign' , $archetype );
2013-08-04 22:16:03 +02:00
$this -> assertInternalType ( 'array' , $result );
2013-06-17 11:27:42 +02:00
$result = get_default_role_archetype_allows ( 'override' , $archetype );
2013-08-04 22:16:03 +02:00
$this -> assertInternalType ( 'array' , $result );
2013-06-17 11:27:42 +02:00
$result = get_default_role_archetype_allows ( 'switch' , $archetype );
2013-08-04 22:16:03 +02:00
$this -> assertInternalType ( 'array' , $result );
2017-11-15 15:08:10 +00:00
$result = get_default_role_archetype_allows ( 'view' , $archetype );
$this -> assertInternalType ( 'array' , $result );
2013-06-17 11:27:42 +02:00
}
$result = get_default_role_archetype_allows ( 'assign' , '' );
$this -> assertSame ( array (), $result );
$result = get_default_role_archetype_allows ( 'override' , '' );
$this -> assertSame ( array (), $result );
$result = get_default_role_archetype_allows ( 'switch' , '' );
$this -> assertSame ( array (), $result );
2017-11-15 15:08:10 +00:00
$result = get_default_role_archetype_allows ( 'view' , '' );
$this -> assertSame ( array (), $result );
2013-06-17 11:27:42 +02:00
$result = get_default_role_archetype_allows ( 'assign' , 'wrongarchetype' );
$this -> assertSame ( array (), $result );
$this -> assertDebuggingCalled ();
$result = get_default_role_archetype_allows ( 'override' , 'wrongarchetype' );
$this -> assertSame ( array (), $result );
$this -> assertDebuggingCalled ();
$result = get_default_role_archetype_allows ( 'switch' , 'wrongarchetype' );
$this -> assertSame ( array (), $result );
$this -> assertDebuggingCalled ();
2017-11-15 15:08:10 +00:00
$result = get_default_role_archetype_allows ( 'view' , 'wrongarchetype' );
$this -> assertSame ( array (), $result );
$this -> assertDebuggingCalled ();
2013-06-17 11:27:42 +02:00
}
2012-05-16 17:24:17 +02:00
/**
* Test allowing of role assignments .
*/
2017-11-24 12:30:40 +00:00
public function test_core_role_set_assign_allowed () {
2013-08-08 11:07:22 +08:00
global $DB , $CFG ;
2012-05-16 17:24:17 +02:00
$this -> resetAfterTest ();
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_assign' , array ( 'roleid' => $otherid , 'allowassign' => $student -> id )));
2017-11-24 12:30:40 +00:00
core_role_set_assign_allowed ( $otherid , $student -> id );
2012-05-16 17:24:17 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_assign' , array ( 'roleid' => $otherid , 'allowassign' => $student -> id )));
2013-08-08 11:07:22 +08:00
// Test event trigger.
$allowroleassignevent = \core\event\role_allow_assign_updated :: create ( array ( 'context' => context_system :: instance ()));
$sink = $this -> redirectEvents ();
$allowroleassignevent -> trigger ();
$events = $sink -> get_events ();
$sink -> close ();
$event = array_pop ( $events );
$this -> assertInstanceOf ( '\core\event\role_allow_assign_updated' , $event );
$mode = 'assign' ;
$baseurl = new moodle_url ( '/admin/roles/allow.php' , array ( 'mode' => $mode ));
$expectedlegacylog = array ( SITEID , 'role' , 'edit allow ' . $mode , str_replace ( $CFG -> wwwroot . '/' , '' , $baseurl ));
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2012-05-16 17:24:17 +02:00
}
/**
* Test allowing of role overrides .
*/
2017-11-24 12:30:40 +00:00
public function test_core_role_set_override_allowed () {
2013-08-08 11:07:22 +08:00
global $DB , $CFG ;
2012-05-16 17:24:17 +02:00
$this -> resetAfterTest ();
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_override' , array ( 'roleid' => $otherid , 'allowoverride' => $student -> id )));
2017-11-24 12:30:40 +00:00
core_role_set_override_allowed ( $otherid , $student -> id );
2012-05-16 17:24:17 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_override' , array ( 'roleid' => $otherid , 'allowoverride' => $student -> id )));
2013-08-08 11:07:22 +08:00
// Test event trigger.
$allowroleassignevent = \core\event\role_allow_override_updated :: create ( array ( 'context' => context_system :: instance ()));
$sink = $this -> redirectEvents ();
$allowroleassignevent -> trigger ();
$events = $sink -> get_events ();
$sink -> close ();
$event = array_pop ( $events );
$this -> assertInstanceOf ( '\core\event\role_allow_override_updated' , $event );
$mode = 'override' ;
$baseurl = new moodle_url ( '/admin/roles/allow.php' , array ( 'mode' => $mode ));
$expectedlegacylog = array ( SITEID , 'role' , 'edit allow ' . $mode , str_replace ( $CFG -> wwwroot . '/' , '' , $baseurl ));
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2012-05-16 17:24:17 +02:00
}
/**
* Test allowing of role switching .
*/
2017-11-24 12:30:40 +00:00
public function test_core_role_set_switch_allowed () {
2013-08-08 11:07:22 +08:00
global $DB , $CFG ;
2012-05-16 17:24:17 +02:00
$this -> resetAfterTest ();
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_switch' , array ( 'roleid' => $otherid , 'allowswitch' => $student -> id )));
2017-11-24 12:30:40 +00:00
core_role_set_switch_allowed ( $otherid , $student -> id );
2012-05-16 17:24:17 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_switch' , array ( 'roleid' => $otherid , 'allowswitch' => $student -> id )));
2013-08-08 11:07:22 +08:00
// Test event trigger.
$allowroleassignevent = \core\event\role_allow_switch_updated :: create ( array ( 'context' => context_system :: instance ()));
$sink = $this -> redirectEvents ();
$allowroleassignevent -> trigger ();
$events = $sink -> get_events ();
$sink -> close ();
$event = array_pop ( $events );
$this -> assertInstanceOf ( '\core\event\role_allow_switch_updated' , $event );
$mode = 'switch' ;
$baseurl = new moodle_url ( '/admin/roles/allow.php' , array ( 'mode' => $mode ));
$expectedlegacylog = array ( SITEID , 'role' , 'edit allow ' . $mode , str_replace ( $CFG -> wwwroot . '/' , '' , $baseurl ));
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
2012-05-16 17:24:17 +02:00
}
2017-11-15 15:08:10 +00:00
/**
* Test allowing of role switching .
*/
2017-11-24 12:30:40 +00:00
public function test_core_role_set_view_allowed () {
2017-11-15 15:08:10 +00:00
global $DB , $CFG ;
$this -> resetAfterTest ();
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$this -> assertFalse ( $DB -> record_exists ( 'role_allow_view' , array ( 'roleid' => $otherid , 'allowview' => $student -> id )));
2017-11-24 12:30:40 +00:00
core_role_set_view_allowed ( $otherid , $student -> id );
2017-11-15 15:08:10 +00:00
$this -> assertTrue ( $DB -> record_exists ( 'role_allow_view' , array ( 'roleid' => $otherid , 'allowview' => $student -> id )));
// Test event trigger.
$allowroleassignevent = \core\event\role_allow_view_updated :: create ( array ( 'context' => context_system :: instance ()));
$sink = $this -> redirectEvents ();
$allowroleassignevent -> trigger ();
$events = $sink -> get_events ();
$sink -> close ();
$event = array_pop ( $events );
$this -> assertInstanceOf ( '\core\event\role_allow_view_updated' , $event );
$mode = 'view' ;
$baseurl = new moodle_url ( '/admin/roles/allow.php' , array ( 'mode' => $mode ));
$expectedlegacylog = array ( SITEID , 'role' , 'edit allow ' . $mode , str_replace ( $CFG -> wwwroot . '/' , '' , $baseurl ));
$this -> assertEventLegacyLogData ( $expectedlegacylog , $event );
}
2012-05-16 17:24:17 +02:00
/**
* Test returning of assignable roles in context .
*/
public function test_get_assignable_roles () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
2014-04-16 20:46:00 -07:00
$teacherename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
2012-05-16 17:24:17 +02:00
$DB -> insert_record ( 'role_names' , $teacherename );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$student = $this -> getDataGenerator () -> create_user ();
role_assign ( $studentrole -> id , $student -> id , $coursecontext );
$contexts = $DB -> get_records ( 'context' );
$users = $DB -> get_records ( 'user' );
$allroles = $DB -> get_records ( 'role' );
// Evaluate all results for all users in all contexts.
2013-07-27 10:58:11 +02:00
foreach ( $users as $user ) {
2012-05-16 17:24:17 +02:00
$this -> setUser ( $user );
2013-07-27 10:58:11 +02:00
foreach ( $contexts as $contextid => $unused ) {
2012-05-16 17:24:17 +02:00
$context = context_helper :: instance_by_id ( $contextid );
$roles = get_assignable_roles ( $context , ROLENAME_SHORT );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $role ) {
2012-05-16 17:24:17 +02:00
if ( isset ( $roles [ $roleid ])) {
if ( is_siteadmin ()) {
$this -> assertTrue ( $DB -> record_exists ( 'role_context_levels' , array ( 'contextlevel' => $context -> contextlevel , 'roleid' => $roleid )));
} else {
$this -> assertTrue ( user_can_assign ( $context , $roleid ), " u: $user->id r: $roleid " );
}
$this -> assertEquals ( $role -> shortname , $roles [ $roleid ]);
} else {
$allowed = $DB -> record_exists ( 'role_context_levels' , array ( 'contextlevel' => $context -> contextlevel , 'roleid' => $roleid ));
if ( is_siteadmin ()) {
$this -> assertFalse ( $allowed );
} else {
$this -> assertFalse ( $allowed and user_can_assign ( $context , $roleid ), " u: $user->id , r: { $allroles [ $roleid ] -> name } , c: $context->contextlevel " );
}
}
}
}
}
2013-07-27 10:58:11 +02:00
// Not-logged-in user.
2012-05-16 17:24:17 +02:00
$this -> setUser ( 0 );
2013-07-27 10:58:11 +02:00
foreach ( $contexts as $contextid => $unused ) {
2012-05-16 17:24:17 +02:00
$context = context_helper :: instance_by_id ( $contextid );
$roles = get_assignable_roles ( $context , ROLENAME_SHORT );
$this -> assertSame ( array (), $roles );
}
// Test current user.
$this -> setUser ( 0 );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ), '*' , MUST_EXIST );
$roles1 = get_assignable_roles ( $coursecontext , ROLENAME_SHORT , false , $admin );
$roles2 = get_assignable_roles ( $coursecontext , ROLENAME_SHORT , false , $admin -> id );
$this -> setAdminUser ();
$roles3 = get_assignable_roles ( $coursecontext , ROLENAME_SHORT );
$this -> assertSame ( $roles1 , $roles3 );
$this -> assertSame ( $roles2 , $roles3 );
// Test parameter defaults.
$this -> setAdminUser ();
$roles1 = get_assignable_roles ( $coursecontext );
$roles2 = get_assignable_roles ( $coursecontext , ROLENAME_ALIAS , false , $admin );
$this -> assertEquals ( $roles2 , $roles1 );
// Verify returned names - let's allow all roles everywhere to simplify this a bit.
$alllevels = context_helper :: get_all_levels ();
$alllevels = array_keys ( $alllevels );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $role ) {
2012-05-16 17:24:17 +02:00
set_role_contextlevels ( $roleid , $alllevels );
}
$alltypes = array ( ROLENAME_ALIAS , ROLENAME_ALIAS_RAW , ROLENAME_BOTH , ROLENAME_ORIGINAL , ROLENAME_ORIGINALANDSHORT , ROLENAME_SHORT );
foreach ( $alltypes as $type ) {
$rolenames = role_fix_names ( $allroles , $coursecontext , $type );
$roles = get_assignable_roles ( $coursecontext , $type , false , $admin );
2013-07-27 10:58:11 +02:00
foreach ( $roles as $roleid => $rolename ) {
2012-05-16 17:24:17 +02:00
$this -> assertSame ( $rolenames [ $roleid ] -> localname , $rolename );
}
}
// Verify counts.
2012-05-18 11:40:35 +02:00
$alltypes = array ( ROLENAME_ALIAS , ROLENAME_ALIAS_RAW , ROLENAME_BOTH , ROLENAME_ORIGINAL , ROLENAME_ORIGINALANDSHORT , ROLENAME_SHORT );
foreach ( $alltypes as $type ) {
$roles = get_assignable_roles ( $coursecontext , $type , false , $admin );
list ( $rolenames , $rolecounts , $nameswithcounts ) = get_assignable_roles ( $coursecontext , $type , true , $admin );
$this -> assertEquals ( $roles , $rolenames );
2013-07-27 10:58:11 +02:00
foreach ( $rolenames as $roleid => $name ) {
2012-05-18 11:40:35 +02:00
if ( $roleid == $teacherrole -> id or $roleid == $studentrole -> id ) {
$this -> assertEquals ( 1 , $rolecounts [ $roleid ]);
} else {
$this -> assertEquals ( 0 , $rolecounts [ $roleid ]);
}
2013-07-27 10:58:11 +02:00
$this -> assertSame ( " $name ( $rolecounts[$roleid] ) " , $nameswithcounts [ $roleid ]);
2012-05-16 17:24:17 +02:00
}
}
}
2019-03-08 12:32:24 +00:00
/**
* Test user count of assignable roles in context where users are assigned the role via different components .
*/
public function test_get_assignable_roles_distinct_usercount () {
global $DB ;
$this -> resetAfterTest ( true );
$this -> setAdminUser ();
$course = $this -> getDataGenerator () -> create_course ();
$context = \context_course :: instance ( $course -> id );
$user1 = $this -> getDataGenerator () -> create_user ();
$user2 = $this -> getDataGenerator () -> create_user ();
$studentrole = $DB -> get_record ( 'role' , [ 'shortname' => 'student' ]);
// Assign each user the student role in course.
role_assign ( $studentrole -> id , $user1 -> id , $context -> id );
role_assign ( $studentrole -> id , $user2 -> id , $context -> id );
list ( $rolenames , $rolecounts , $nameswithcounts ) = get_assignable_roles ( $context , ROLENAME_SHORT , true );
$this -> assertEquals ( 2 , $rolecounts [ $studentrole -> id ]);
// Assign first user the student role in course again (this time via 'enrol_self' component).
role_assign ( $studentrole -> id , $user1 -> id , $context -> id , 'enrol_self' , 1 );
// There are still only two distinct users.
list ( $rolenames , $rolecounts , $nameswithcounts ) = get_assignable_roles ( $context , ROLENAME_SHORT , true );
$this -> assertEquals ( 2 , $rolecounts [ $studentrole -> id ]);
}
2012-05-16 17:24:17 +02:00
/**
* Test getting of all switchable roles .
*/
public function test_get_switchable_roles () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
2014-04-16 20:46:00 -07:00
$teacherename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
2012-05-16 17:24:17 +02:00
$DB -> insert_record ( 'role_names' , $teacherename );
$contexts = $DB -> get_records ( 'context' );
$users = $DB -> get_records ( 'user' );
$allroles = $DB -> get_records ( 'role' );
// Evaluate all results for all users in all contexts.
2013-07-27 10:58:11 +02:00
foreach ( $users as $user ) {
2012-05-16 17:24:17 +02:00
$this -> setUser ( $user );
2013-07-27 10:58:11 +02:00
foreach ( $contexts as $contextid => $unused ) {
2012-05-16 17:24:17 +02:00
$context = context_helper :: instance_by_id ( $contextid );
$roles = get_switchable_roles ( $context );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $role ) {
2012-05-16 17:24:17 +02:00
if ( is_siteadmin ()) {
$this -> assertTrue ( isset ( $roles [ $roleid ]));
} else {
$parents = $context -> get_parent_context_ids ( true );
$pcontexts = implode ( ',' , $parents );
$allowed = $DB -> record_exists_sql (
" SELECT r.id
FROM { role } r
JOIN { role_allow_switch } ras ON ras . allowswitch = r . id
JOIN { role_assignments } ra ON ra . roleid = ras . roleid
WHERE ra . userid = : userid AND ra . contextid IN ( $pcontexts ) AND r . id = : roleid
" ,
array ( 'userid' => $user -> id , 'roleid' => $roleid )
);
if ( isset ( $roles [ $roleid ])) {
$this -> assertTrue ( $allowed );
} else {
$this -> assertFalse ( $allowed );
}
}
if ( isset ( $roles [ $roleid ])) {
$coursecontext = $context -> get_course_context ( false );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( role_get_name ( $role , $coursecontext ), $roles [ $roleid ]);
2012-05-16 17:24:17 +02:00
}
}
}
}
}
/**
* Test getting of all overridable roles .
*/
public function test_get_overridable_roles () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
2014-04-16 20:46:00 -07:00
$teacherename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
2012-05-16 17:24:17 +02:00
$DB -> insert_record ( 'role_names' , $teacherename );
2013-07-27 10:58:11 +02:00
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' ))); // Any capability is ok.
2014-04-16 20:46:00 -07:00
assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $teacherrole -> id , $coursecontext -> id );
2012-05-16 17:24:17 +02:00
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$student = $this -> getDataGenerator () -> create_user ();
role_assign ( $studentrole -> id , $student -> id , $coursecontext );
$contexts = $DB -> get_records ( 'context' );
$users = $DB -> get_records ( 'user' );
$allroles = $DB -> get_records ( 'role' );
// Evaluate all results for all users in all contexts.
2013-07-27 10:58:11 +02:00
foreach ( $users as $user ) {
2012-05-16 17:24:17 +02:00
$this -> setUser ( $user );
2013-07-27 10:58:11 +02:00
foreach ( $contexts as $contextid => $unused ) {
2012-05-16 17:24:17 +02:00
$context = context_helper :: instance_by_id ( $contextid );
$roles = get_overridable_roles ( $context , ROLENAME_SHORT );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $role ) {
2012-05-16 17:24:17 +02:00
$hascap = has_any_capability ( array ( 'moodle/role:safeoverride' , 'moodle/role:override' ), $context );
if ( is_siteadmin ()) {
$this -> assertTrue ( isset ( $roles [ $roleid ]));
} else {
$parents = $context -> get_parent_context_ids ( true );
$pcontexts = implode ( ',' , $parents );
$allowed = $DB -> record_exists_sql (
" SELECT r.id
FROM { role } r
JOIN { role_allow_override } rao ON r . id = rao . allowoverride
JOIN { role_assignments } ra ON rao . roleid = ra . roleid
WHERE ra . userid = : userid AND ra . contextid IN ( $pcontexts ) AND r . id = : roleid
" ,
array ( 'userid' => $user -> id , 'roleid' => $roleid )
);
if ( isset ( $roles [ $roleid ])) {
$this -> assertTrue ( $hascap );
$this -> assertTrue ( $allowed );
} else {
$this -> assertFalse ( $hascap and $allowed );
}
}
if ( isset ( $roles [ $roleid ])) {
2012-05-18 11:40:35 +02:00
$this -> assertEquals ( $role -> shortname , $roles [ $roleid ]);
2012-05-16 17:24:17 +02:00
}
}
}
}
// Test parameter defaults.
$this -> setAdminUser ();
$roles1 = get_overridable_roles ( $coursecontext );
$roles2 = get_overridable_roles ( $coursecontext , ROLENAME_ALIAS , false );
$this -> assertEquals ( $roles2 , $roles1 );
$alltypes = array ( ROLENAME_ALIAS , ROLENAME_ALIAS_RAW , ROLENAME_BOTH , ROLENAME_ORIGINAL , ROLENAME_ORIGINALANDSHORT , ROLENAME_SHORT );
foreach ( $alltypes as $type ) {
$rolenames = role_fix_names ( $allroles , $coursecontext , $type );
$roles = get_overridable_roles ( $coursecontext , $type , false );
2013-07-27 10:58:11 +02:00
foreach ( $roles as $roleid => $rolename ) {
2012-05-16 17:24:17 +02:00
$this -> assertSame ( $rolenames [ $roleid ] -> localname , $rolename );
}
}
// Verify counts.
$roles = get_overridable_roles ( $coursecontext , ROLENAME_ALIAS , false );
list ( $rolenames , $rolecounts , $nameswithcounts ) = get_overridable_roles ( $coursecontext , ROLENAME_ALIAS , true );
$this -> assertEquals ( $roles , $rolenames );
2013-07-27 10:58:11 +02:00
foreach ( $rolenames as $roleid => $name ) {
2012-05-16 17:24:17 +02:00
if ( $roleid == $teacherrole -> id ) {
$this -> assertEquals ( 1 , $rolecounts [ $roleid ]);
} else {
$this -> assertEquals ( 0 , $rolecounts [ $roleid ]);
}
2013-07-27 10:58:11 +02:00
$this -> assertSame ( " $name ( $rolecounts[$roleid] ) " , $nameswithcounts [ $roleid ]);
2012-05-16 17:24:17 +02:00
}
}
2017-11-15 15:08:10 +00:00
/**
* Test getting of all overridable roles .
*/
public function test_get_viewable_roles_course () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$studentrolerename = ( object ) array ( 'roleid' => $studentrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $studentrolerename );
// By default teacher can see student.
$this -> setUser ( $teacher );
$viewableroles = get_viewable_roles ( $coursecontext );
$this -> assertContains ( $studentrolerename -> name , array_values ( $viewableroles ));
// Remove view permission.
$DB -> delete_records ( 'role_allow_view' , array ( 'roleid' => $teacherrole -> id , 'allowview' => $studentrole -> id ));
$viewableroles = get_viewable_roles ( $coursecontext );
// Teacher can no longer see student role.
$this -> assertNotContains ( $studentrolerename -> name , array_values ( $viewableroles ));
// Allow again teacher to view student.
2017-11-24 12:30:40 +00:00
core_role_set_view_allowed ( $teacherrole -> id , $studentrole -> id );
2017-11-15 15:08:10 +00:00
// Teacher can now see student role.
$viewableroles = get_viewable_roles ( $coursecontext );
$this -> assertContains ( $studentrolerename -> name , array_values ( $viewableroles ));
}
/**
* Test getting of all overridable roles .
*/
public function test_get_viewable_roles_system () {
global $DB ;
$this -> resetAfterTest ();
$context = context_system :: instance ();
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $teacher -> id , $context );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$studentrolename = role_get_name ( $studentrole , $context );
// By default teacher can see student.
$this -> setUser ( $teacher );
$viewableroles = get_viewable_roles ( $context );
$this -> assertContains ( $studentrolename , array_values ( $viewableroles ));
// Remove view permission.
$DB -> delete_records ( 'role_allow_view' , array ( 'roleid' => $teacherrole -> id , 'allowview' => $studentrole -> id ));
$viewableroles = get_viewable_roles ( $context );
// Teacher can no longer see student role.
$this -> assertNotContains ( $studentrolename , array_values ( $viewableroles ));
// Allow again teacher to view student.
2017-11-24 12:30:40 +00:00
core_role_set_view_allowed ( $teacherrole -> id , $studentrole -> id );
2017-11-15 15:08:10 +00:00
// Teacher can now see student role.
$viewableroles = get_viewable_roles ( $context );
$this -> assertContains ( $studentrolename , array_values ( $viewableroles ));
}
2012-05-16 17:24:17 +02:00
/**
* Test we have context level defaults .
*/
public function test_get_default_contextlevels () {
$archetypes = get_role_archetypes ();
$alllevels = context_helper :: get_all_levels ();
foreach ( $archetypes as $archetype ) {
$defaults = get_default_contextlevels ( $archetype );
2013-08-04 22:16:03 +02:00
$this -> assertInternalType ( 'array' , $defaults );
2012-05-16 17:24:17 +02:00
foreach ( $defaults as $level ) {
$this -> assertTrue ( isset ( $alllevels [ $level ]));
}
}
}
/**
* Test role context level setup .
*/
public function test_set_role_contextlevels () {
global $DB ;
$this -> resetAfterTest ();
$roleid = create_role ( 'New student role' , 'student2' , 'New student description' , 'student' );
$this -> assertFalse ( $DB -> record_exists ( 'role_context_levels' , array ( 'roleid' => $roleid )));
set_role_contextlevels ( $roleid , array ( CONTEXT_COURSE , CONTEXT_MODULE ));
$levels = $DB -> get_records ( 'role_context_levels' , array ( 'roleid' => $roleid ), '' , 'contextlevel, contextlevel' );
$this -> assertCount ( 2 , $levels );
$this -> assertTrue ( isset ( $levels [ CONTEXT_COURSE ]));
$this -> assertTrue ( isset ( $levels [ CONTEXT_MODULE ]));
set_role_contextlevels ( $roleid , array ( CONTEXT_COURSE ));
$levels = $DB -> get_records ( 'role_context_levels' , array ( 'roleid' => $roleid ), '' , 'contextlevel, contextlevel' );
$this -> assertCount ( 1 , $levels );
$this -> assertTrue ( isset ( $levels [ CONTEXT_COURSE ]));
}
/**
* Test getting of role context levels
*/
public function test_get_roles_for_contextlevels () {
global $DB ;
$allroles = get_all_roles ();
2013-07-27 10:58:11 +02:00
foreach ( context_helper :: get_all_levels () as $level => $unused ) {
2012-05-16 17:24:17 +02:00
$roles = get_roles_for_contextlevels ( $level );
2013-07-27 10:58:11 +02:00
foreach ( $allroles as $roleid => $unused ) {
2012-05-16 17:24:17 +02:00
$exists = $DB -> record_exists ( 'role_context_levels' , array ( 'contextlevel' => $level , 'roleid' => $roleid ));
if ( in_array ( $roleid , $roles )) {
$this -> assertTrue ( $exists );
} else {
$this -> assertFalse ( $exists );
}
}
}
}
/**
* Test default enrol roles .
*/
public function test_get_default_enrol_roles () {
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$id2 = create_role ( 'New student role' , 'student2' , 'New student description' , 'student' );
set_role_contextlevels ( $id2 , array ( CONTEXT_COURSE ));
$allroles = get_all_roles ();
$expected = array ( $id2 => $allroles [ $id2 ]);
2013-07-27 10:58:11 +02:00
foreach ( get_role_archetypes () as $archetype ) {
2012-05-16 17:24:17 +02:00
$defaults = get_default_contextlevels ( $archetype );
if ( in_array ( CONTEXT_COURSE , $defaults )) {
$roles = get_archetype_roles ( $archetype );
2013-07-27 10:58:11 +02:00
foreach ( $roles as $role ) {
2012-05-16 17:24:17 +02:00
$expected [ $role -> id ] = $role ;
}
}
}
$roles = get_default_enrol_roles ( $coursecontext );
foreach ( $allroles as $role ) {
$this -> assertEquals ( isset ( $expected [ $role -> id ]), isset ( $roles [ $role -> id ]));
if ( isset ( $roles [ $role -> id ])) {
2013-07-27 10:58:11 +02:00
$this -> assertSame ( role_get_name ( $role , $coursecontext ), $roles [ $role -> id ]);
2012-05-16 17:24:17 +02:00
}
}
}
2012-05-18 11:40:35 +02:00
/**
* Test getting of role users .
*/
public function test_get_role_users () {
2013-05-25 10:09:42 +02:00
global $DB ;
2012-07-10 10:00:34 +08:00
2012-05-18 11:40:35 +02:00
$this -> resetAfterTest ();
$systemcontext = context_system :: instance ();
2012-12-06 15:26:43 +01:00
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
2012-05-18 11:40:35 +02:00
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
2014-11-17 15:03:57 +08:00
$noeditteacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ), '*' , MUST_EXIST );
2012-05-18 11:40:35 +02:00
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$teacherrename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherrename );
$otherrename = ( object ) array ( 'roleid' => $otherid , 'name' => 'Ostatní' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $otherrename );
2013-05-25 10:09:42 +02:00
$user1 = $this -> getDataGenerator () -> create_user ( array ( 'firstname' => 'John' , 'lastname' => 'Smith' ));
2012-05-18 11:40:35 +02:00
role_assign ( $teacherrole -> id , $user1 -> id , $coursecontext -> id );
2013-05-25 10:09:42 +02:00
$user2 = $this -> getDataGenerator () -> create_user ( array ( 'firstname' => 'Jan' , 'lastname' => 'Kovar' ));
2012-05-18 11:40:35 +02:00
role_assign ( $teacherrole -> id , $user2 -> id , $systemcontext -> id );
2012-12-06 15:26:43 +01:00
$user3 = $this -> getDataGenerator () -> create_user ();
$this -> getDataGenerator () -> enrol_user ( $user3 -> id , $course -> id , $teacherrole -> id );
$user4 = $this -> getDataGenerator () -> create_user ();
$this -> getDataGenerator () -> enrol_user ( $user4 -> id , $course -> id , $studentrole -> id );
2014-11-17 15:03:57 +08:00
$this -> getDataGenerator () -> enrol_user ( $user4 -> id , $course -> id , $noeditteacherrole -> id );
2012-12-06 15:26:43 +01:00
$group = $this -> getDataGenerator () -> create_group ( array ( 'courseid' => $course -> id ));
2013-05-25 10:09:42 +02:00
groups_add_member ( $group , $user3 );
2012-05-18 11:40:35 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext );
2013-05-25 10:09:42 +02:00
$this -> assertCount ( 2 , $users );
$this -> assertArrayHasKey ( $user1 -> id , $users );
$this -> assertEquals ( $users [ $user1 -> id ] -> id , $user1 -> id );
$this -> assertEquals ( $users [ $user1 -> id ] -> roleid , $teacherrole -> id );
$this -> assertEquals ( $users [ $user1 -> id ] -> rolename , $teacherrole -> name );
$this -> assertEquals ( $users [ $user1 -> id ] -> roleshortname , $teacherrole -> shortname );
$this -> assertEquals ( $users [ $user1 -> id ] -> rolecoursealias , $teacherrename -> name );
$this -> assertArrayHasKey ( $user3 -> id , $users );
$this -> assertEquals ( $users [ $user3 -> id ] -> id , $user3 -> id );
$this -> assertEquals ( $users [ $user3 -> id ] -> roleid , $teacherrole -> id );
$this -> assertEquals ( $users [ $user3 -> id ] -> rolename , $teacherrole -> name );
$this -> assertEquals ( $users [ $user3 -> id ] -> roleshortname , $teacherrole -> shortname );
$this -> assertEquals ( $users [ $user3 -> id ] -> rolecoursealias , $teacherrename -> name );
2012-05-18 11:40:35 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , true );
2013-05-25 10:09:42 +02:00
$this -> assertCount ( 3 , $users );
2012-12-06 15:26:43 +01:00
2013-05-25 10:09:42 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , true , '' , null , null , '' , 2 , 1 );
$this -> assertCount ( 1 , $users );
2012-12-06 15:26:43 +01:00
2013-05-25 10:09:42 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , false , 'u.id, u.email, u.idnumber' , 'u.idnumber' );
2012-05-18 11:40:35 +02:00
$this -> assertCount ( 2 , $users );
2013-05-25 10:09:42 +02:00
$this -> assertArrayHasKey ( $user1 -> id , $users );
$this -> assertArrayHasKey ( $user3 -> id , $users );
2016-03-04 15:43:36 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , false , 'u.id, u.email' );
$this -> assertDebuggingCalled ( 'get_role_users() adding u.lastname, u.firstname to the query result because they were required by $sort but missing in $fields' );
$this -> assertCount ( 2 , $users );
$this -> assertArrayHasKey ( $user1 -> id , $users );
$this -> assertObjectHasAttribute ( 'lastname' , $users [ $user1 -> id ]);
$this -> assertObjectHasAttribute ( 'firstname' , $users [ $user1 -> id ]);
$this -> assertArrayHasKey ( $user3 -> id , $users );
$this -> assertObjectHasAttribute ( 'lastname' , $users [ $user3 -> id ]);
$this -> assertObjectHasAttribute ( 'firstname' , $users [ $user3 -> id ]);
2016-08-14 15:03:23 +03:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , false , 'u.id AS id_alias' );
$this -> assertDebuggingCalled ( 'get_role_users() adding u.lastname, u.firstname to the query result because they were required by $sort but missing in $fields' );
$this -> assertCount ( 2 , $users );
$this -> assertArrayHasKey ( $user1 -> id , $users );
$this -> assertObjectHasAttribute ( 'id_alias' , $users [ $user1 -> id ]);
$this -> assertObjectHasAttribute ( 'lastname' , $users [ $user1 -> id ]);
$this -> assertObjectHasAttribute ( 'firstname' , $users [ $user1 -> id ]);
$this -> assertArrayHasKey ( $user3 -> id , $users );
$this -> assertObjectHasAttribute ( 'id_alias' , $users [ $user3 -> id ]);
$this -> assertObjectHasAttribute ( 'lastname' , $users [ $user3 -> id ]);
$this -> assertObjectHasAttribute ( 'firstname' , $users [ $user3 -> id ]);
2013-05-25 10:09:42 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , false , 'u.id, u.email, u.idnumber' , 'u.idnumber' , null , $group -> id );
$this -> assertCount ( 1 , $users );
$this -> assertArrayHasKey ( $user3 -> id , $users );
2012-05-18 11:40:35 +02:00
2013-05-25 10:09:42 +02:00
$users = get_role_users ( $teacherrole -> id , $coursecontext , true , 'u.id, u.email, u.idnumber, u.firstname' , 'u.idnumber' , null , '' , '' , '' , 'u.firstname = :xfirstname' , array ( 'xfirstname' => 'John' ));
$this -> assertCount ( 1 , $users );
$this -> assertArrayHasKey ( $user1 -> id , $users );
2014-11-17 15:03:57 +08:00
$users = get_role_users ( array ( $noeditteacherrole -> id , $studentrole -> id ), $coursecontext , false , 'ra.id' , 'ra.id' );
$this -> assertDebuggingNotCalled ();
$users = get_role_users ( array ( $noeditteacherrole -> id , $studentrole -> id ), $coursecontext , false , 'ra.userid' , 'ra.userid' );
$this -> assertDebuggingCalled ( 'get_role_users() without specifying one single roleid needs to be called prefixing ' .
'role assignments id (ra.id) as unique field, you can use $fields param for it.' );
$users = get_role_users ( array ( $noeditteacherrole -> id , $studentrole -> id ), $coursecontext , false );
$this -> assertDebuggingCalled ( 'get_role_users() without specifying one single roleid needs to be called prefixing ' .
'role assignments id (ra.id) as unique field, you can use $fields param for it.' );
$users = get_role_users ( array ( $noeditteacherrole -> id , $studentrole -> id ), $coursecontext ,
false , 'u.id, u.firstname' , 'u.id, u.firstname' );
$this -> assertDebuggingCalled ( 'get_role_users() without specifying one single roleid needs to be called prefixing ' .
'role assignments id (ra.id) as unique field, you can use $fields param for it.' );
2012-05-18 11:40:35 +02:00
}
/**
* Test used role query .
*/
public function test_get_roles_used_in_context () {
global $DB ;
$this -> resetAfterTest ();
$systemcontext = context_system :: instance ();
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$otherid = create_role ( 'Other role' , 'other' , 'Some other role' , '' );
$teacherrename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherrename );
$otherrename = ( object ) array ( 'roleid' => $otherid , 'name' => 'Ostatní' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $otherrename );
$user1 = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $user1 -> id , $coursecontext -> id );
$roles = get_roles_used_in_context ( $coursecontext );
$this -> assertCount ( 1 , $roles );
$role = reset ( $roles );
$roleid = key ( $roles );
$this -> assertEquals ( $roleid , $role -> id );
$this -> assertEquals ( $teacherrole -> id , $role -> id );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $teacherrole -> name , $role -> name );
$this -> assertSame ( $teacherrole -> shortname , $role -> shortname );
2012-05-18 11:40:35 +02:00
$this -> assertEquals ( $teacherrole -> sortorder , $role -> sortorder );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $teacherrename -> name , $role -> coursealias );
2012-05-18 11:40:35 +02:00
$user2 = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $user2 -> id , $systemcontext -> id );
role_assign ( $otherid , $user2 -> id , $systemcontext -> id );
$roles = get_roles_used_in_context ( $systemcontext );
$this -> assertCount ( 2 , $roles );
}
/**
* Test roles used in course .
*/
public function test_get_user_roles_in_course () {
global $DB , $CFG ;
$this -> resetAfterTest ();
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
2017-09-14 15:23:04 +08:00
$managerrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'manager' ), '*' , MUST_EXIST );
2012-05-18 11:40:35 +02:00
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherrename );
2013-07-27 10:58:11 +02:00
$roleids = explode ( ',' , $CFG -> profileroles ); // Should include teacher and student in new installs.
2012-05-18 11:40:35 +02:00
$this -> assertTrue ( in_array ( $teacherrole -> id , $roleids ));
$this -> assertTrue ( in_array ( $studentrole -> id , $roleids ));
2017-09-14 15:23:04 +08:00
$this -> assertFalse ( in_array ( $managerrole -> id , $roleids ));
2012-05-18 11:40:35 +02:00
$user1 = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $user1 -> id , $coursecontext -> id );
role_assign ( $studentrole -> id , $user1 -> id , $coursecontext -> id );
$user2 = $this -> getDataGenerator () -> create_user ();
role_assign ( $studentrole -> id , $user2 -> id , $coursecontext -> id );
$user3 = $this -> getDataGenerator () -> create_user ();
2017-09-14 15:23:04 +08:00
$user4 = $this -> getDataGenerator () -> create_user ();
role_assign ( $managerrole -> id , $user4 -> id , $coursecontext -> id );
2012-05-18 11:40:35 +02:00
2017-11-15 15:08:10 +00:00
$this -> setAdminUser ();
2012-05-18 11:40:35 +02:00
$roles = get_user_roles_in_course ( $user1 -> id , $course -> id );
2012-07-10 10:11:50 +08:00
$this -> assertEquals ( 1 , preg_match_all ( '/,/' , $roles , $matches ));
2012-05-18 11:40:35 +02:00
$this -> assertTrue ( strpos ( $roles , role_get_name ( $teacherrole , $coursecontext )) !== false );
$roles = get_user_roles_in_course ( $user2 -> id , $course -> id );
2012-07-10 10:11:50 +08:00
$this -> assertEquals ( 0 , preg_match_all ( '/,/' , $roles , $matches ));
2012-05-18 11:40:35 +02:00
$this -> assertTrue ( strpos ( $roles , role_get_name ( $studentrole , $coursecontext )) !== false );
$roles = get_user_roles_in_course ( $user3 -> id , $course -> id );
$this -> assertSame ( '' , $roles );
2017-09-14 15:23:04 +08:00
// Managers should be able to see a link to their own role type, given they can assign it in the context.
$this -> setUser ( $user4 );
$roles = get_user_roles_in_course ( $user4 -> id , $course -> id );
$this -> assertNotEmpty ( $roles );
$this -> assertEquals ( 1 , count ( explode ( ',' , $roles )));
$this -> assertTrue ( strpos ( $roles , role_get_name ( $managerrole , $coursecontext )) !== false );
// Managers should see 2 roles if viewing a user who has been enrolled as a student and a teacher in the course.
$roles = get_user_roles_in_course ( $user1 -> id , $course -> id );
$this -> assertEquals ( 2 , count ( explode ( ',' , $roles )));
$this -> assertTrue ( strpos ( $roles , role_get_name ( $studentrole , $coursecontext )) !== false );
$this -> assertTrue ( strpos ( $roles , role_get_name ( $teacherrole , $coursecontext )) !== false );
// Students should not see the manager role if viewing a manager's profile.
$this -> setUser ( $user2 );
$roles = get_user_roles_in_course ( $user4 -> id , $course -> id );
$this -> assertEmpty ( $roles ); // Should see 0 roles on the manager's profile.
$this -> assertFalse ( strpos ( $roles , role_get_name ( $managerrole , $coursecontext )) !== false );
2012-05-18 11:40:35 +02:00
}
2017-07-26 11:20:35 +08:00
/**
* Test get_user_roles and get_users_roles
*/
public function test_get_user_roles () {
global $DB , $CFG ;
$this -> resetAfterTest ();
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrename = ( object ) array ( 'roleid' => $teacherrole -> id , 'name' => 'Učitel' , 'contextid' => $coursecontext -> id );
$DB -> insert_record ( 'role_names' , $teacherrename );
$roleids = explode ( ',' , $CFG -> profileroles ); // Should include teacher and student in new installs.
$user1 = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $user1 -> id , $coursecontext -> id );
role_assign ( $studentrole -> id , $user1 -> id , $coursecontext -> id );
$user2 = $this -> getDataGenerator () -> create_user ();
role_assign ( $studentrole -> id , $user2 -> id , $coursecontext -> id );
$user3 = $this -> getDataGenerator () -> create_user ();
$u1roles = get_user_roles ( $coursecontext , $user1 -> id );
2017-07-26 13:30:44 +08:00
2017-07-26 11:20:35 +08:00
$u2roles = get_user_roles ( $coursecontext , $user2 -> id );
2018-05-14 15:26:04 +01:00
$allroles = get_users_roles ( $coursecontext , [], false );
2017-07-26 11:20:35 +08:00
$specificuserroles = get_users_roles ( $coursecontext , [ $user1 -> id , $user2 -> id ]);
$this -> assertEquals ( $u1roles , $allroles [ $user1 -> id ]);
$this -> assertEquals ( $u1roles , $specificuserroles [ $user1 -> id ]);
$this -> assertEquals ( $u2roles , $allroles [ $user2 -> id ]);
$this -> assertEquals ( $u2roles , $specificuserroles [ $user2 -> id ]);
}
2012-05-16 17:24:17 +02:00
/**
* Test has_capability (), has_any_capability () and has_all_capabilities () .
*/
public function test_has_capability_and_friends () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ));
// Note: Here are used default capabilities, the full test is in permission evaluation bellow,
// use two capabilities that teacher has and one does not, none of them should be allowed for not-logged-in user.
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupsection' )));
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' )));
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/site:approvecourse' )));
$sca = array ( 'moodle/backup:backupsection' , 'moodle/backup:backupcourse' , 'moodle/site:approvecourse' );
$sc = array ( 'moodle/backup:backupsection' , 'moodle/backup:backupcourse' );
$this -> setUser ( 0 );
$this -> assertFalse ( has_capability ( 'moodle/backup:backupsection' , $coursecontext ));
$this -> assertFalse ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext ));
$this -> assertFalse ( has_capability ( 'moodle/site:approvecourse' , $coursecontext ));
$this -> assertFalse ( has_any_capability ( $sca , $coursecontext ));
$this -> assertFalse ( has_all_capabilities ( $sca , $coursecontext ));
$this -> assertTrue ( has_capability ( 'moodle/backup:backupsection' , $coursecontext , $teacher ));
$this -> assertTrue ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext , $teacher ));
$this -> assertFalse ( has_capability ( 'moodle/site:approvecourse' , $coursecontext , $teacher ));
$this -> assertTrue ( has_any_capability ( $sca , $coursecontext , $teacher ));
$this -> assertTrue ( has_all_capabilities ( $sc , $coursecontext , $teacher ));
$this -> assertFalse ( has_all_capabilities ( $sca , $coursecontext , $teacher ));
$this -> assertTrue ( has_capability ( 'moodle/backup:backupsection' , $coursecontext , $admin ));
$this -> assertTrue ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext , $admin ));
$this -> assertTrue ( has_capability ( 'moodle/site:approvecourse' , $coursecontext , $admin ));
$this -> assertTrue ( has_any_capability ( $sca , $coursecontext , $admin ));
$this -> assertTrue ( has_all_capabilities ( $sc , $coursecontext , $admin ));
$this -> assertTrue ( has_all_capabilities ( $sca , $coursecontext , $admin ));
$this -> assertFalse ( has_capability ( 'moodle/backup:backupsection' , $coursecontext , $admin , false ));
$this -> assertFalse ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext , $admin , false ));
$this -> assertFalse ( has_capability ( 'moodle/site:approvecourse' , $coursecontext , $admin , false ));
$this -> assertFalse ( has_any_capability ( $sca , $coursecontext , $admin , false ));
$this -> assertFalse ( has_all_capabilities ( $sc , $coursecontext , $admin , false ));
$this -> assertFalse ( has_all_capabilities ( $sca , $coursecontext , $admin , false ));
$this -> setUser ( $teacher );
$this -> assertTrue ( has_capability ( 'moodle/backup:backupsection' , $coursecontext ));
$this -> assertTrue ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext ));
$this -> assertFalse ( has_capability ( 'moodle/site:approvecourse' , $coursecontext ));
$this -> assertTrue ( has_any_capability ( $sca , $coursecontext ));
$this -> assertTrue ( has_all_capabilities ( $sc , $coursecontext ));
$this -> assertFalse ( has_all_capabilities ( $sca , $coursecontext ));
$this -> setAdminUser ();
$this -> assertTrue ( has_capability ( 'moodle/backup:backupsection' , $coursecontext ));
$this -> assertTrue ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext ));
$this -> assertTrue ( has_capability ( 'moodle/site:approvecourse' , $coursecontext ));
$this -> assertTrue ( has_any_capability ( $sca , $coursecontext ));
$this -> assertTrue ( has_all_capabilities ( $sc , $coursecontext ));
$this -> assertTrue ( has_all_capabilities ( $sca , $coursecontext ));
$this -> assertFalse ( has_capability ( 'moodle/backup:backupsection' , $coursecontext , 0 ));
$this -> assertFalse ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext , 0 ));
$this -> assertFalse ( has_capability ( 'moodle/site:approvecourse' , $coursecontext , 0 ));
$this -> assertFalse ( has_any_capability ( $sca , $coursecontext , 0 ));
$this -> assertFalse ( has_all_capabilities ( $sca , $coursecontext , 0 ));
}
2019-02-28 08:39:20 +08:00
/**
* Test that assigning a fake cap does not return .
*/
public function test_fake_capability () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
$fakecapname = 'moodle/fake:capability' ;
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ));
// Test a capability which does not exist.
// Note: Do not use assign_capability because it will not allow fake caps.
$DB -> insert_record ( 'role_capabilities' , ( object ) [
'contextid' => $coursecontext -> id ,
'roleid' => $teacherrole -> id ,
'capability' => $fakecapname ,
'permission' => CAP_ALLOW ,
'timemodified' => time (),
'modifierid' => 0 ,
]);
// Check `has_capability`.
$this -> assertFalse ( has_capability ( $fakecapname , $coursecontext , $teacher ));
$this -> assertDebuggingCalled ( " Capability \" { $fakecapname } \" was not found! This has to be fixed in code. " );
$this -> assertFalse ( has_capability ( $fakecapname , $coursecontext , $admin ));
$this -> assertDebuggingCalled ( " Capability \" { $fakecapname } \" was not found! This has to be fixed in code. " );
// Check `get_with_capability_sql` (with uses `get_with_capability_join`).
list ( $sql , $params ) = get_with_capability_sql ( $coursecontext , $fakecapname );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertFalse ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
// Check `get_users_by_capability`.
$users = get_users_by_capability ( $coursecontext , $fakecapname );
$this -> assertFalse ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
}
/**
* Test that assigning a fake cap does not return .
*/
public function test_fake_capability_assign () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
$capability = 'moodle/fake:capability' ;
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ));
$this -> expectException ( 'coding_exception' );
$this -> expectExceptionMessage ( " Capability ' { $capability } ' was not found! This has to be fixed in code. " );
assign_capability ( $capability , CAP_ALLOW , $teacherrole -> id , $coursecontext );
}
/**
* Test that assigning a fake cap does not return .
*/
public function test_fake_capability_unassign () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
$capability = 'moodle/fake:capability' ;
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ));
$this -> expectException ( 'coding_exception' );
$this -> expectExceptionMessage ( " Capability ' { $capability } ' was not found! This has to be fixed in code. " );
unassign_capability ( $capability , CAP_ALLOW , $teacherrole -> id , $coursecontext );
}
2018-06-19 14:42:26 +01:00
/**
* Test that the caching in get_role_definitions () and get_role_definitions_uncached ()
* works as intended .
*/
public function test_role_definition_caching () {
global $DB ;
$this -> resetAfterTest ();
// Get some role ids.
$authenticatedrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'user' ), '*' , MUST_EXIST );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$emptyroleid = create_role ( 'No capabilities' , 'empty' , 'A role with no capabilties' );
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
// Instantiate the cache instance, since that does DB queries (get_config)
// and we don't care about those.
cache :: make ( 'core' , 'roledefs' );
// One database query is not necessarily one database read, it seems. Find out how many.
$startdbreads = $DB -> perf_get_reads ();
$rs = $DB -> get_recordset ( 'user' );
$rs -> close ();
$readsperquery = $DB -> perf_get_reads () - $startdbreads ;
// Now load some role definitions, and check when it queries the database.
// Load the capabilities for two roles. Should be one query.
$startdbreads = $DB -> perf_get_reads ();
get_role_definitions ([ $authenticatedrole -> id , $studentrole -> id ]);
$this -> assertEquals ( 1 * $readsperquery , $DB -> perf_get_reads () - $startdbreads );
// Load the capabilities for same two roles. Should not query the DB.
$startdbreads = $DB -> perf_get_reads ();
get_role_definitions ([ $authenticatedrole -> id , $studentrole -> id ]);
$this -> assertEquals ( 0 * $readsperquery , $DB -> perf_get_reads () - $startdbreads );
// Include a third role. Should do one DB query.
$startdbreads = $DB -> perf_get_reads ();
get_role_definitions ([ $authenticatedrole -> id , $studentrole -> id , $emptyroleid ]);
$this -> assertEquals ( 1 * $readsperquery , $DB -> perf_get_reads () - $startdbreads );
// Repeat call. No DB queries.
$startdbreads = $DB -> perf_get_reads ();
get_role_definitions ([ $authenticatedrole -> id , $studentrole -> id , $emptyroleid ]);
$this -> assertEquals ( 0 * $readsperquery , $DB -> perf_get_reads () - $startdbreads );
// Alter a role.
role_change_permission ( $studentrole -> id , $coursecontext , 'moodle/course:tag' , CAP_ALLOW );
// Should now know to do one query.
$startdbreads = $DB -> perf_get_reads ();
get_role_definitions ([ $authenticatedrole -> id , $studentrole -> id ]);
$this -> assertEquals ( 1 * $readsperquery , $DB -> perf_get_reads () - $startdbreads );
// Now clear the in-memory cache, and verify that it does not query the DB.
// Cannot use accesslib_clear_all_caches_for_unit_testing since that also
// clears the MUC cache.
global $ACCESSLIB_PRIVATE ;
$ACCESSLIB_PRIVATE -> cacheroledefs = array ();
// Get all roles. Should not need the DB.
$startdbreads = $DB -> perf_get_reads ();
get_role_definitions ([ $authenticatedrole -> id , $studentrole -> id , $emptyroleid ]);
$this -> assertEquals ( 0 * $readsperquery , $DB -> perf_get_reads () - $startdbreads );
}
2017-08-22 18:09:35 +01:00
/**
* Tests get_user_capability_course () which checks a capability across all courses .
*/
public function test_get_user_capability_course () {
global $CFG , $USER ;
$this -> resetAfterTest ();
$generator = $this -> getDataGenerator ();
$cap = 'moodle/course:view' ;
2017-12-06 19:40:38 +00:00
// The structure being created here is this:
//
// All tests work with the single capability 'moodle/course:view'.
//
// ROLE DEF/OVERRIDE ROLE ASSIGNS
// Role: Allow Prohib Empty Def user u1 u2 u3 u4 u5 u6 u7 u8
// System ALLOW PROHIBIT A E A+E
// cat1 ALLOW
// C1 (ALLOW) P
// C2 ALLOW E P
// cat2 PREVENT
// C3 ALLOW E
// C4
// Misc. A
// C5 PREVENT A
// C6 PROHIBIT
//
// Front-page and guest role stuff from the end of this test not included in the diagram.
2017-08-22 18:09:35 +01:00
// Create a role which allows course:view and one that prohibits it, and one neither.
$allowroleid = $generator -> create_role ();
$prohibitroleid = $generator -> create_role ();
$emptyroleid = $generator -> create_role ();
$systemcontext = context_system :: instance ();
assign_capability ( $cap , CAP_ALLOW , $allowroleid , $systemcontext -> id );
assign_capability ( $cap , CAP_PROHIBIT , $prohibitroleid , $systemcontext -> id );
// Create two categories (nested).
$cat1 = $generator -> create_category ();
$cat2 = $generator -> create_category ([ 'parent' => $cat1 -> id ]);
// Create six courses - two in cat1, two in cat2, and two in default category.
2017-12-06 19:40:38 +00:00
// Shortnames are used for a sorting test. Otherwise they are not significant.
2017-08-22 18:09:35 +01:00
$c1 = $generator -> create_course ([ 'category' => $cat1 -> id , 'shortname' => 'Z' ]);
$c2 = $generator -> create_course ([ 'category' => $cat1 -> id , 'shortname' => 'Y' ]);
$c3 = $generator -> create_course ([ 'category' => $cat2 -> id , 'shortname' => 'X' ]);
$c4 = $generator -> create_course ([ 'category' => $cat2 -> id ]);
$c5 = $generator -> create_course ();
$c6 = $generator -> create_course ();
// Category overrides: in cat 1, empty role is allowed; in cat 2, empty role is prevented.
assign_capability ( $cap , CAP_ALLOW , $emptyroleid ,
context_coursecat :: instance ( $cat1 -> id ) -> id );
assign_capability ( $cap , CAP_PREVENT , $emptyroleid ,
context_coursecat :: instance ( $cat2 -> id ) -> id );
// Course overrides: in C5, allow role is prevented; in C6, empty role is prohibited; in
// C3, empty role is allowed.
assign_capability ( $cap , CAP_PREVENT , $allowroleid ,
context_course :: instance ( $c5 -> id ) -> id );
assign_capability ( $cap , CAP_PROHIBIT , $emptyroleid ,
context_course :: instance ( $c6 -> id ) -> id );
assign_capability ( $cap , CAP_ALLOW , $emptyroleid ,
context_course :: instance ( $c3 -> id ) -> id );
2017-12-06 19:40:38 +00:00
assign_capability ( $cap , CAP_ALLOW , $prohibitroleid ,
context_course :: instance ( $c2 -> id ) -> id );
2017-08-22 18:09:35 +01:00
// User 1 has no roles except default user role.
$u1 = $generator -> create_user ();
// It returns false (annoyingly) if there are no courses.
$this -> assertFalse ( get_user_capability_course ( $cap , $u1 -> id , true , '' , 'id' ));
// Final override: in C1, default user role is allowed.
assign_capability ( $cap , CAP_ALLOW , $CFG -> defaultuserroleid ,
context_course :: instance ( $c1 -> id ) -> id );
// Should now get C1 only.
$courses = get_user_capability_course ( $cap , $u1 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ $c1 -> id ], $courses );
// User 2 has allow role (system wide).
$u2 = $generator -> create_user ();
role_assign ( $allowroleid , $u2 -> id , $systemcontext -> id );
// Should get everything except C5.
$courses = get_user_capability_course ( $cap , $u2 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ SITEID , $c1 -> id , $c2 -> id , $c3 -> id , $c4 -> id , $c6 -> id ], $courses );
// User 3 has empty role (system wide).
$u3 = $generator -> create_user ();
role_assign ( $emptyroleid , $u3 -> id , $systemcontext -> id );
// Should get cat 1 courses but not cat2, except C3.
$courses = get_user_capability_course ( $cap , $u3 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ $c1 -> id , $c2 -> id , $c3 -> id ], $courses );
// User 4 has allow and empty role (system wide).
$u4 = $generator -> create_user ();
role_assign ( $allowroleid , $u4 -> id , $systemcontext -> id );
role_assign ( $emptyroleid , $u4 -> id , $systemcontext -> id );
// Should get everything except C5 and C6.
$courses = get_user_capability_course ( $cap , $u4 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ SITEID , $c1 -> id , $c2 -> id , $c3 -> id , $c4 -> id ], $courses );
// User 5 has allow role in default category only.
$u5 = $generator -> create_user ();
role_assign ( $allowroleid , $u5 -> id , context_coursecat :: instance ( $c5 -> category ) -> id );
// Should get C1 and the default category courses but not C5.
$courses = get_user_capability_course ( $cap , $u5 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ $c1 -> id , $c6 -> id ], $courses );
// User 6 has a bunch of course roles: prohibit role in C1, empty role in C3, allow role in
// C6.
$u6 = $generator -> create_user ();
role_assign ( $prohibitroleid , $u6 -> id , context_course :: instance ( $c1 -> id ) -> id );
role_assign ( $emptyroleid , $u6 -> id , context_course :: instance ( $c3 -> id ) -> id );
role_assign ( $allowroleid , $u6 -> id , context_course :: instance ( $c5 -> id ) -> id );
// Should get C3 only because the allow role is prevented in C5.
$courses = get_user_capability_course ( $cap , $u6 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ $c3 -> id ], $courses );
2017-12-06 19:40:38 +00:00
// User 7 has empty role in C2.
$u7 = $generator -> create_user ();
role_assign ( $emptyroleid , $u7 -> id , context_course :: instance ( $c2 -> id ) -> id );
// Should get C1 by the default user role override, and C2 by the cat1 level override.
$courses = get_user_capability_course ( $cap , $u7 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ $c1 -> id , $c2 -> id ], $courses );
// User 8 has prohibit role as system context, to verify that prohibits can't be overridden.
$u8 = $generator -> create_user ();
role_assign ( $prohibitroleid , $u8 -> id , context_course :: instance ( $c2 -> id ) -> id );
// Should get C1 by the default user role override, no other courses because the prohibit cannot be overridden.
$courses = get_user_capability_course ( $cap , $u8 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ $c1 -> id ], $courses );
2017-08-22 18:09:35 +01:00
// Admin user gets everything....
$courses = get_user_capability_course ( $cap , get_admin () -> id , true , '' , 'id' );
$this -> assert_course_ids ([ SITEID , $c1 -> id , $c2 -> id , $c3 -> id , $c4 -> id , $c5 -> id , $c6 -> id ],
$courses );
// Unless you turn off doanything, when it only has the things a user with no role does.
$courses = get_user_capability_course ( $cap , get_admin () -> id , false , '' , 'id' );
$this -> assert_course_ids ([ $c1 -> id ], $courses );
// Using u3 as an example, test the limit feature.
$courses = get_user_capability_course ( $cap , $u3 -> id , true , '' , 'id' , 2 );
$this -> assert_course_ids ([ $c1 -> id , $c2 -> id ], $courses );
// Check sorting.
$courses = get_user_capability_course ( $cap , $u3 -> id , true , '' , 'shortname' );
$this -> assert_course_ids ([ $c3 -> id , $c2 -> id , $c1 -> id ], $courses );
// Check returned fields - default.
$courses = get_user_capability_course ( $cap , $u3 -> id , true , '' , 'id' );
$this -> assertEquals (( object )[ 'id' => $c1 -> id ], $courses [ 0 ]);
// Add a selection of fields, including the context ones with special handling.
$courses = get_user_capability_course ( $cap , $u3 -> id , true , 'shortname, ctxlevel, ctxdepth, ctxinstance' , 'id' );
$this -> assertEquals (( object )[ 'id' => $c1 -> id , 'shortname' => 'Z' , 'ctxlevel' => 50 ,
'ctxdepth' => 3 , 'ctxinstance' => $c1 -> id ], $courses [ 0 ]);
// Test front page role - user 1 has no roles, but if we change the front page role
// definition so that it has our capability, then they should see the front page course.
// as well as C1.
assign_capability ( $cap , CAP_ALLOW , $CFG -> defaultfrontpageroleid , $systemcontext -> id );
$courses = get_user_capability_course ( $cap , $u1 -> id , true , '' , 'id' );
$this -> assert_course_ids ([ SITEID , $c1 -> id ], $courses );
// Check that temporary guest access (in this case, given on course 2 for user 1)
// also is included, if it has this capability.
assign_capability ( $cap , CAP_ALLOW , $CFG -> guestroleid , $systemcontext -> id );
$this -> setUser ( $u1 );
load_temp_course_role ( context_course :: instance ( $c2 -> id ), $CFG -> guestroleid );
$courses = get_user_capability_course ( $cap , $USER -> id , true , '' , 'id' );
$this -> assert_course_ids ([ SITEID , $c1 -> id , $c2 -> id ], $courses );
}
/**
* Extracts an array of course ids to make the above test script shorter .
*
* @ param int [] $expected Array of expected course ids
* @ param stdClass [] $courses Array of course objects
*/
protected function assert_course_ids ( array $expected , array $courses ) {
$courseids = array_map ( function ( $c ) {
return $c -> id ;
}, $courses );
$this -> assertEquals ( $expected , $courseids );
}
2013-07-21 11:47:40 +02:00
/**
* Test if course creator future capability lookup works .
*/
2013-07-23 15:55:07 +02:00
public function test_guess_if_creator_will_have_course_capability () {
2013-07-21 11:47:40 +02:00
global $DB , $CFG , $USER ;
$this -> resetAfterTest ();
$category = $this -> getDataGenerator () -> create_category ();
$course = $this -> getDataGenerator () -> create_course ( array ( 'category' => $category -> id ));
$syscontext = context_system :: instance ();
$categorycontext = context_coursecat :: instance ( $category -> id );
$coursecontext = context_course :: instance ( $course -> id );
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$creatorrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'coursecreator' ), '*' , MUST_EXIST );
$managerrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'manager' ), '*' , MUST_EXIST );
$this -> assertEquals ( $teacherrole -> id , $CFG -> creatornewroleid );
$creator = $this -> getDataGenerator () -> create_user ();
$manager = $this -> getDataGenerator () -> create_user ();
role_assign ( $managerrole -> id , $manager -> id , $categorycontext );
$this -> assertFalse ( has_capability ( 'moodle/course:view' , $categorycontext , $creator ));
$this -> assertFalse ( has_capability ( 'moodle/role:assign' , $categorycontext , $creator ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , $creator ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , $creator ));
2013-07-23 15:55:07 +02:00
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $creator ));
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $creator ));
2013-07-21 11:47:40 +02:00
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $categorycontext , $manager ));
$this -> assertTrue ( has_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertTrue ( has_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $manager -> id ));
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $manager -> id ));
2013-07-21 11:47:40 +02:00
$this -> assertEquals ( 0 , $USER -> id );
$this -> assertFalse ( has_capability ( 'moodle/course:view' , $categorycontext ));
$this -> assertFalse ( has_capability ( 'moodle/role:assign' , $categorycontext ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext ));
2013-07-23 15:55:07 +02:00
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext ));
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext ));
2013-07-21 11:47:40 +02:00
$this -> setUser ( $manager );
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $categorycontext ));
$this -> assertTrue ( has_capability ( 'moodle/course:visibility' , $categorycontext ));
$this -> assertTrue ( has_capability ( 'moodle/course:visibility' , $coursecontext ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext ));
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext ));
2013-07-21 11:47:40 +02:00
$this -> setAdminUser ();
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $categorycontext ));
$this -> assertTrue ( has_capability ( 'moodle/course:visibility' , $categorycontext ));
$this -> assertTrue ( has_capability ( 'moodle/course:visibility' , $coursecontext ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext ));
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext ));
2013-07-21 11:47:40 +02:00
$this -> setUser ( 0 );
role_assign ( $creatorrole -> id , $creator -> id , $categorycontext );
$this -> assertFalse ( has_capability ( 'moodle/role:assign' , $categorycontext , $creator ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , $creator ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , $creator ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $creator ));
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $creator ));
2013-07-21 11:47:40 +02:00
$this -> setUser ( $creator );
$this -> assertFalse ( has_capability ( 'moodle/role:assign' , $categorycontext , null ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , null ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , null ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , null ));
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , null ));
2013-07-21 11:47:40 +02:00
$this -> setUser ( 0 );
set_config ( 'creatornewroleid' , $studentrole -> id );
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , $creator ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , $creator ));
2013-07-23 15:55:07 +02:00
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $creator ));
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $creator ));
2013-07-21 11:47:40 +02:00
set_config ( 'creatornewroleid' , $teacherrole -> id );
role_change_permission ( $managerrole -> id , $categorycontext , 'moodle/course:visibility' , CAP_PREVENT );
role_assign ( $creatorrole -> id , $manager -> id , $categorycontext );
$this -> assertTrue ( has_capability ( 'moodle/course:view' , $categorycontext , $manager ));
$this -> assertTrue ( has_capability ( 'moodle/course:view' , $coursecontext , $manager ));
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $categorycontext , $manager ));
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $coursecontext , $manager ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-23 15:55:07 +02:00
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-21 11:47:40 +02:00
role_change_permission ( $managerrole -> id , $categorycontext , 'moodle/course:view' , CAP_PREVENT );
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $categorycontext , $manager ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-21 11:47:40 +02:00
$this -> getDataGenerator () -> enrol_user ( $manager -> id , $course -> id , 0 );
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $categorycontext , $manager ));
$this -> assertTrue ( has_capability ( 'moodle/role:assign' , $coursecontext , $manager ));
$this -> assertTrue ( is_enrolled ( $coursecontext , $manager ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertFalse ( has_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-23 15:55:07 +02:00
$this -> assertTrue ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $categorycontext , $manager ));
$this -> assertFalse ( guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $coursecontext , $manager ));
2013-07-21 11:47:40 +02:00
// Test problems.
try {
2013-07-23 15:55:07 +02:00
guess_if_creator_will_have_course_capability ( 'moodle/course:visibility' , $syscontext , $creator );
$this -> fail ( 'Exception expected when non course/category context passed to guess_if_creator_will_have_course_capability()' );
2013-07-21 11:47:40 +02:00
} catch ( moodle_exception $e ) {
$this -> assertInstanceOf ( 'coding_exception' , $e );
}
}
2012-05-16 17:24:17 +02:00
/**
* Test require_capability () exceptions .
*/
public function test_require_capability () {
$this -> resetAfterTest ();
$syscontext = context_system :: instance ();
$this -> setUser ( 0 );
$this -> assertFalse ( has_capability ( 'moodle/site:config' , $syscontext ));
try {
require_capability ( 'moodle/site:config' , $syscontext );
$this -> fail ( 'Exception expected from require_capability()' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-05-16 17:24:17 +02:00
$this -> assertInstanceOf ( 'required_capability_exception' , $e );
}
$this -> setAdminUser ();
$this -> assertFalse ( has_capability ( 'moodle/site:config' , $syscontext , 0 ));
try {
require_capability ( 'moodle/site:config' , $syscontext , 0 );
$this -> fail ( 'Exception expected from require_capability()' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-05-16 17:24:17 +02:00
$this -> assertInstanceOf ( 'required_capability_exception' , $e );
}
$this -> assertFalse ( has_capability ( 'moodle/site:config' , $syscontext , null , false ));
try {
require_capability ( 'moodle/site:config' , $syscontext , null , false );
$this -> fail ( 'Exception expected from require_capability()' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-05-16 17:24:17 +02:00
$this -> assertInstanceOf ( 'required_capability_exception' , $e );
}
}
2015-03-05 11:37:21 +10:30
/**
2015-04-07 15:17:38 +08:00
* Test that enrolled users SQL does not return any values for users in
* other courses .
2015-03-05 11:37:21 +10:30
*/
2015-04-07 15:17:38 +08:00
public function test_get_enrolled_sql_different_course () {
global $DB ;
2015-03-05 11:37:21 +10:30
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$context = context_course :: instance ( $course -> id );
2015-04-07 15:17:38 +08:00
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
2015-03-05 11:37:21 +10:30
$user = $this -> getDataGenerator () -> create_user ();
// This user should not appear anywhere, we're not interested in that context.
$course2 = $this -> getDataGenerator () -> create_course ();
2015-04-07 15:17:38 +08:00
$this -> getDataGenerator () -> enrol_user ( $user -> id , $course2 -> id , $student -> id );
$enrolled = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , false );
$active = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , true );
$suspended = get_suspended_userids ( $context );
$this -> assertFalse ( isset ( $enrolled [ $user -> id ]));
$this -> assertFalse ( isset ( $active [ $user -> id ]));
$this -> assertFalse ( isset ( $suspended [ $user -> id ]));
$this -> assertCount ( 0 , $enrolled );
$this -> assertCount ( 0 , $active );
$this -> assertCount ( 0 , $suspended );
}
/**
* Test that enrolled users SQL does not return any values for role
* assignments without an enrolment .
*/
public function test_get_enrolled_sql_role_only () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$context = context_course :: instance ( $course -> id );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$user = $this -> getDataGenerator () -> create_user ();
2015-03-05 11:37:21 +10:30
// Role assignment is not the same as course enrollment.
2015-04-07 15:17:38 +08:00
role_assign ( $student -> id , $user -> id , $context -> id );
$enrolled = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , false );
$active = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , true );
$suspended = get_suspended_userids ( $context );
$this -> assertFalse ( isset ( $enrolled [ $user -> id ]));
2015-03-05 11:37:21 +10:30
$this -> assertFalse ( isset ( $active [ $user -> id ]));
2015-04-07 15:17:38 +08:00
$this -> assertFalse ( isset ( $suspended [ $user -> id ]));
$this -> assertCount ( 0 , $enrolled );
2015-03-05 11:37:21 +10:30
$this -> assertCount ( 0 , $active );
2015-04-07 15:17:38 +08:00
$this -> assertCount ( 0 , $suspended );
}
/**
* Test that multiple enrolments for the same user are counted correctly .
*/
public function test_get_enrolled_sql_multiple_enrolments () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$context = context_course :: instance ( $course -> id );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$user = $this -> getDataGenerator () -> create_user ();
2015-03-05 11:37:21 +10:30
// Add a suspended enrol.
2015-04-07 15:17:38 +08:00
$selfinstance = $DB -> get_record ( 'enrol' , array ( 'courseid' => $course -> id , 'enrol' => 'self' ));
$selfplugin = enrol_get_plugin ( 'self' );
$selfplugin -> update_status ( $selfinstance , ENROL_INSTANCE_ENABLED );
$this -> getDataGenerator () -> enrol_user ( $user -> id , $course -> id , $student -> id , 'self' , 0 , 0 , ENROL_USER_SUSPENDED );
2015-03-05 11:37:21 +10:30
// Should be enrolled, but not active - user is suspended.
2015-04-07 15:17:38 +08:00
$enrolled = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , false );
$active = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , true );
$suspended = get_suspended_userids ( $context );
$this -> assertTrue ( isset ( $enrolled [ $user -> id ]));
2015-03-05 11:37:21 +10:30
$this -> assertFalse ( isset ( $active [ $user -> id ]));
2015-04-07 15:17:38 +08:00
$this -> assertTrue ( isset ( $suspended [ $user -> id ]));
$this -> assertCount ( 1 , $enrolled );
2015-03-05 11:37:21 +10:30
$this -> assertCount ( 0 , $active );
2015-04-07 15:17:38 +08:00
$this -> assertCount ( 1 , $suspended );
2015-03-05 11:37:21 +10:30
// Add an active enrol for the user. Any active enrol makes them enrolled.
2015-04-07 15:17:38 +08:00
$this -> getDataGenerator () -> enrol_user ( $user -> id , $course -> id , $student -> id );
2015-03-05 11:37:21 +10:30
// User should be active now.
2015-04-07 15:17:38 +08:00
$enrolled = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , false );
$active = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , true );
$suspended = get_suspended_userids ( $context );
$this -> assertTrue ( isset ( $enrolled [ $user -> id ]));
2015-03-05 11:37:21 +10:30
$this -> assertTrue ( isset ( $active [ $user -> id ]));
2015-04-07 15:17:38 +08:00
$this -> assertFalse ( isset ( $suspended [ $user -> id ]));
$this -> assertCount ( 1 , $enrolled );
2015-03-05 11:37:21 +10:30
$this -> assertCount ( 1 , $active );
2015-04-07 15:17:38 +08:00
$this -> assertCount ( 0 , $suspended );
}
2018-07-13 11:28:59 +02:00
/**
* Test that enrolled users SQL does not return any values for users
* without a group when $context is not a valid course context .
*/
public function test_get_enrolled_sql_userswithoutgroup () {
global $DB ;
$this -> resetAfterTest ();
$systemcontext = context_system :: instance ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$user1 = $this -> getDataGenerator () -> create_user ();
$user2 = $this -> getDataGenerator () -> create_user ();
$this -> getDataGenerator () -> enrol_user ( $user1 -> id , $course -> id );
$this -> getDataGenerator () -> enrol_user ( $user2 -> id , $course -> id );
$group = $this -> getDataGenerator () -> create_group ( array ( 'courseid' => $course -> id ));
groups_add_member ( $group , $user1 );
$enrolled = get_enrolled_users ( $coursecontext );
$this -> assertCount ( 2 , $enrolled );
// Get users without any group on the course context.
$enrolledwithoutgroup = get_enrolled_users ( $coursecontext , '' , USERSWITHOUTGROUP );
$this -> assertCount ( 1 , $enrolledwithoutgroup );
$this -> assertFalse ( isset ( $enrolledwithoutgroup [ $user1 -> id ]));
// Get users without any group on the system context (it should throw an exception).
$this -> expectException ( 'coding_exception' );
get_enrolled_users ( $systemcontext , '' , USERSWITHOUTGROUP );
}
2015-04-07 15:17:38 +08:00
public function get_enrolled_sql_provider () {
return array (
array (
// Two users who are enrolled.
'users' => array (
array (
'enrolled' => true ,
'active' => true ,
),
array (
'enrolled' => true ,
'active' => true ,
),
),
'counts' => array (
'enrolled' => 2 ,
'active' => 2 ,
'suspended' => 0 ,
),
),
array (
// A user who is suspended.
'users' => array (
array (
'status' => ENROL_USER_SUSPENDED ,
'enrolled' => true ,
'suspended' => true ,
),
),
'counts' => array (
'enrolled' => 1 ,
'active' => 0 ,
'suspended' => 1 ,
),
),
array (
// One of each.
'users' => array (
array (
'enrolled' => true ,
'active' => true ,
),
array (
'status' => ENROL_USER_SUSPENDED ,
'enrolled' => true ,
'suspended' => true ,
),
),
'counts' => array (
'enrolled' => 2 ,
'active' => 1 ,
'suspended' => 1 ,
),
),
array (
// One user who is not yet enrolled.
'users' => array (
array (
'timestart' => DAYSECS ,
'enrolled' => true ,
'active' => false ,
'suspended' => true ,
),
),
'counts' => array (
'enrolled' => 1 ,
'active' => 0 ,
'suspended' => 1 ,
),
),
array (
// One user who is no longer enrolled
'users' => array (
array (
'timeend' => - DAYSECS ,
'enrolled' => true ,
'active' => false ,
'suspended' => true ,
),
),
'counts' => array (
'enrolled' => 1 ,
'active' => 0 ,
'suspended' => 1 ,
),
),
array (
// One user who is not yet enrolled, and one who is no longer enrolled.
'users' => array (
array (
'timeend' => - DAYSECS ,
'enrolled' => true ,
'active' => false ,
'suspended' => true ,
),
array (
'timestart' => DAYSECS ,
'enrolled' => true ,
'active' => false ,
'suspended' => true ,
),
),
'counts' => array (
'enrolled' => 2 ,
'active' => 0 ,
'suspended' => 2 ,
),
),
);
}
/**
* @ dataProvider get_enrolled_sql_provider
*/
public function test_get_enrolled_sql_course ( $users , $counts ) {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$context = context_course :: instance ( $course -> id );
$student = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$createdusers = array ();
foreach ( $users as & $userdata ) {
$user = $this -> getDataGenerator () -> create_user ();
$userdata [ 'id' ] = $user -> id ;
$timestart = 0 ;
$timeend = 0 ;
$status = null ;
if ( isset ( $userdata [ 'timestart' ])) {
$timestart = time () + $userdata [ 'timestart' ];
}
if ( isset ( $userdata [ 'timeend' ])) {
$timeend = time () + $userdata [ 'timeend' ];
}
if ( isset ( $userdata [ 'status' ])) {
$status = $userdata [ 'status' ];
}
// Enrol the user in the course.
$this -> getDataGenerator () -> enrol_user ( $user -> id , $course -> id , $student -> id , 'manual' , $timestart , $timeend , $status );
}
// After all users have been enroled, check expectations.
$enrolled = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , false );
$active = get_enrolled_users ( $context , '' , 0 , 'u.id' , null , 0 , 0 , true );
$suspended = get_suspended_userids ( $context );
foreach ( $users as $userdata ) {
if ( isset ( $userdata [ 'enrolled' ]) && $userdata [ 'enrolled' ]) {
$this -> assertTrue ( isset ( $enrolled [ $userdata [ 'id' ]]));
} else {
$this -> assertFalse ( isset ( $enrolled [ $userdata [ 'id' ]]));
}
if ( isset ( $userdata [ 'active' ]) && $userdata [ 'active' ]) {
$this -> assertTrue ( isset ( $active [ $userdata [ 'id' ]]));
} else {
$this -> assertFalse ( isset ( $active [ $userdata [ 'id' ]]));
}
if ( isset ( $userdata [ 'suspended' ]) && $userdata [ 'suspended' ]) {
$this -> assertTrue ( isset ( $suspended [ $userdata [ 'id' ]]));
} else {
$this -> assertFalse ( isset ( $suspended [ $userdata [ 'id' ]]));
}
}
$this -> assertCount ( $counts [ 'enrolled' ], $enrolled );
$this -> assertCount ( $counts [ 'active' ], $active );
$this -> assertCount ( $counts [ 'suspended' ], $suspended );
2015-03-05 11:37:21 +10:30
}
2012-05-16 17:24:17 +02:00
/**
* A small functional test of permission evaluations .
*/
public function test_permission_evaluation () {
2012-03-31 23:51:02 +02:00
global $USER , $SITE , $CFG , $DB , $ACCESSLIB_PRIVATE ;
2013-07-27 10:58:11 +02:00
$this -> resetAfterTest ();
2012-03-31 23:51:02 +02:00
$generator = $this -> getDataGenerator ();
2013-07-27 10:58:11 +02:00
// Fill the site with some real data.
2012-03-31 23:51:02 +02:00
$testcategories = array ();
$testcourses = array ();
$testpages = array ();
$testblocks = array ();
$allroles = $DB -> get_records_menu ( 'role' , array (), 'id' , 'archetype, id' );
$systemcontext = context_system :: instance ();
$frontpagecontext = context_course :: instance ( SITEID );
2013-07-27 10:58:11 +02:00
// Add block to system context.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' );
context_block :: instance ( $bi -> id );
$testblocks [] = $bi -> id ;
2013-07-27 10:58:11 +02:00
// Some users.
2012-03-31 23:51:02 +02:00
$testusers = array ();
2013-07-27 10:58:11 +02:00
for ( $i = 0 ; $i < 20 ; $i ++ ) {
2012-03-31 23:51:02 +02:00
$user = $generator -> create_user ();
$testusers [ $i ] = $user -> id ;
$usercontext = context_user :: instance ( $user -> id );
2013-07-27 10:58:11 +02:00
// Add block to user profile.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' , array ( 'parentcontextid' => $usercontext -> id ));
$testblocks [] = $bi -> id ;
}
2013-07-27 10:58:11 +02:00
// Deleted user - should be ignored everywhere, can not have context.
2012-03-31 23:51:02 +02:00
$generator -> create_user ( array ( 'deleted' => 1 ));
2013-07-27 10:58:11 +02:00
// Add block to frontpage.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' , array ( 'parentcontextid' => $frontpagecontext -> id ));
$frontpageblockcontext = context_block :: instance ( $bi -> id );
$testblocks [] = $bi -> id ;
2013-07-27 10:58:11 +02:00
// Add a resource to frontpage.
2012-03-31 23:51:02 +02:00
$page = $generator -> create_module ( 'page' , array ( 'course' => $SITE -> id ));
2014-02-16 13:11:27 +11:00
$testpages [] = $page -> cmid ;
2012-03-31 23:51:02 +02:00
$frontpagepagecontext = context_module :: instance ( $page -> cmid );
2013-07-27 10:58:11 +02:00
// Add block to frontpage resource.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' , array ( 'parentcontextid' => $frontpagepagecontext -> id ));
$frontpagepageblockcontext = context_block :: instance ( $bi -> id );
$testblocks [] = $bi -> id ;
2013-07-27 10:58:11 +02:00
// Some nested course categories with courses.
2012-03-31 23:51:02 +02:00
$manualenrol = enrol_get_plugin ( 'manual' );
$parentcat = 0 ;
2013-07-27 10:58:11 +02:00
for ( $i = 0 ; $i < 5 ; $i ++ ) {
2012-03-31 23:51:02 +02:00
$cat = $generator -> create_category ( array ( 'parent' => $parentcat ));
$testcategories [] = $cat -> id ;
$catcontext = context_coursecat :: instance ( $cat -> id );
$parentcat = $cat -> id ;
2012-05-16 17:24:17 +02:00
if ( $i >= 4 ) {
2012-03-31 23:51:02 +02:00
continue ;
}
2013-07-27 10:58:11 +02:00
// Add resource to each category.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' , array ( 'parentcontextid' => $catcontext -> id ));
context_block :: instance ( $bi -> id );
2013-07-27 10:58:11 +02:00
// Add a few courses to each category.
for ( $j = 0 ; $j < 6 ; $j ++ ) {
2012-03-31 23:51:02 +02:00
$course = $generator -> create_course ( array ( 'category' => $cat -> id ));
$testcourses [] = $course -> id ;
$coursecontext = context_course :: instance ( $course -> id );
if ( $j >= 5 ) {
continue ;
}
2013-07-27 10:58:11 +02:00
// Add manual enrol instance.
2012-03-31 23:51:02 +02:00
$manualenrol -> add_default_instance ( $DB -> get_record ( 'course' , array ( 'id' => $course -> id )));
2013-07-27 10:58:11 +02:00
// Add block to each course.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' , array ( 'parentcontextid' => $coursecontext -> id ));
$testblocks [] = $bi -> id ;
2013-07-27 10:58:11 +02:00
// Add a resource to each course.
2012-03-31 23:51:02 +02:00
$page = $generator -> create_module ( 'page' , array ( 'course' => $course -> id ));
2014-02-16 13:11:27 +11:00
$testpages [] = $page -> cmid ;
2012-03-31 23:51:02 +02:00
$modcontext = context_module :: instance ( $page -> cmid );
2013-07-27 10:58:11 +02:00
// Add block to each module.
2012-03-31 23:51:02 +02:00
$bi = $generator -> create_block ( 'online_users' , array ( 'parentcontextid' => $modcontext -> id ));
$testblocks [] = $bi -> id ;
}
}
2013-07-27 10:58:11 +02:00
// Make sure all contexts were created properly.
$count = 1 ; // System.
2012-03-31 23:51:02 +02:00
$count += $DB -> count_records ( 'user' , array ( 'deleted' => 0 ));
$count += $DB -> count_records ( 'course_categories' );
$count += $DB -> count_records ( 'course' );
$count += $DB -> count_records ( 'course_modules' );
$count += $DB -> count_records ( 'block_instances' );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $count , $DB -> count_records ( 'context' ));
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'depth' => 0 )));
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'path' => null )));
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test context_helper::get_level_name() method.
2012-03-31 23:51:02 +02:00
$levels = context_helper :: get_all_levels ();
2013-07-27 10:58:11 +02:00
foreach ( $levels as $level => $classname ) {
2012-03-31 23:51:02 +02:00
$name = context_helper :: get_level_name ( $level );
2013-07-27 10:58:11 +02:00
$this -> assertNotEmpty ( $name );
2012-03-31 23:51:02 +02:00
}
2013-07-27 10:58:11 +02:00
// Test context::instance_by_id(), context_xxx::instance() methods.
2012-03-31 23:51:02 +02:00
$context = context :: instance_by_id ( $frontpagecontext -> id );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( CONTEXT_COURSE , $context -> contextlevel );
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( context :: instance_by_id ( - 1 , IGNORE_MISSING ));
try {
context :: instance_by_id ( - 1 );
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( true );
}
2013-07-27 10:58:11 +02:00
$this -> assertInstanceOf ( 'context_system' , context_system :: instance ());
$this -> assertInstanceOf ( 'context_coursecat' , context_coursecat :: instance ( $testcategories [ 0 ]));
$this -> assertInstanceOf ( 'context_course' , context_course :: instance ( $testcourses [ 0 ]));
$this -> assertInstanceOf ( 'context_module' , context_module :: instance ( $testpages [ 0 ]));
$this -> assertInstanceOf ( 'context_block' , context_block :: instance ( $testblocks [ 0 ]));
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( context_coursecat :: instance ( - 1 , IGNORE_MISSING ));
$this -> assertFalse ( context_course :: instance ( - 1 , IGNORE_MISSING ));
$this -> assertFalse ( context_module :: instance ( - 1 , IGNORE_MISSING ));
$this -> assertFalse ( context_block :: instance ( - 1 , IGNORE_MISSING ));
try {
context_coursecat :: instance ( - 1 );
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( true );
}
try {
context_course :: instance ( - 1 );
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( true );
}
try {
context_module :: instance ( - 1 );
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( true );
}
try {
context_block :: instance ( - 1 );
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( true );
}
2013-07-27 10:58:11 +02:00
// Test $context->get_url(), $context->get_context_name(), $context->get_capabilities() methods.
2012-03-31 23:51:02 +02:00
$testcontexts = array ();
$testcontexts [ CONTEXT_SYSTEM ] = context_system :: instance ();
$testcontexts [ CONTEXT_COURSECAT ] = context_coursecat :: instance ( $testcategories [ 0 ]);
$testcontexts [ CONTEXT_COURSE ] = context_course :: instance ( $testcourses [ 0 ]);
$testcontexts [ CONTEXT_MODULE ] = context_module :: instance ( $testpages [ 0 ]);
$testcontexts [ CONTEXT_BLOCK ] = context_block :: instance ( $testblocks [ 0 ]);
foreach ( $testcontexts as $context ) {
$name = $context -> get_context_name ( true , true );
2013-07-27 10:58:11 +02:00
$this -> assertNotEmpty ( $name );
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
$this -> assertInstanceOf ( 'moodle_url' , $context -> get_url ());
2012-03-31 23:51:02 +02:00
$caps = $context -> get_capabilities ();
$this -> assertTrue ( is_array ( $caps ));
foreach ( $caps as $cap ) {
$cap = ( array ) $cap ;
$this -> assertSame ( array_keys ( $cap ), array ( 'id' , 'name' , 'captype' , 'contextlevel' , 'component' , 'riskbitmask' ));
}
}
unset ( $testcontexts );
2013-07-27 10:58:11 +02:00
// Test $context->get_course_context() method.
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( $systemcontext -> get_course_context ( false ));
try {
$systemcontext -> get_course_context ();
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
$this -> assertInstanceOf ( 'coding_exception' , $e );
2012-03-31 23:51:02 +02:00
}
$context = context_coursecat :: instance ( $testcategories [ 0 ]);
$this -> assertFalse ( $context -> get_course_context ( false ));
try {
$context -> get_course_context ();
$this -> fail ( 'exception expected' );
2013-07-27 10:58:11 +02:00
} catch ( moodle_exception $e ) {
$this -> assertInstanceOf ( 'coding_exception' , $e );
2012-03-31 23:51:02 +02:00
}
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $frontpagecontext , $frontpagecontext -> get_course_context ( true ));
$this -> assertEquals ( $frontpagecontext , $frontpagepagecontext -> get_course_context ( true ));
$this -> assertEquals ( $frontpagecontext , $frontpagepageblockcontext -> get_course_context ( true ));
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() methods.
2012-03-31 23:51:02 +02:00
$userid = reset ( $testusers );
$usercontext = context_user :: instance ( $userid );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $systemcontext , $usercontext -> get_parent_context ());
$this -> assertEquals ( array ( $systemcontext -> id => $systemcontext ), $usercontext -> get_parent_contexts ());
$this -> assertEquals ( array ( $usercontext -> id => $usercontext , $systemcontext -> id => $systemcontext ), $usercontext -> get_parent_contexts ( true ));
$this -> assertEquals ( array (), $systemcontext -> get_parent_contexts ());
$this -> assertEquals ( array ( $systemcontext -> id => $systemcontext ), $systemcontext -> get_parent_contexts ( true ));
$this -> assertEquals ( array (), $systemcontext -> get_parent_context_ids ());
$this -> assertEquals ( array ( $systemcontext -> id ), $systemcontext -> get_parent_context_ids ( true ));
2018-06-21 13:23:03 -04:00
$this -> assertEquals ( array (), $systemcontext -> get_parent_context_paths ());
$this -> assertEquals ( array ( $systemcontext -> id => $systemcontext -> path ), $systemcontext -> get_parent_context_paths ( true ));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $systemcontext , $frontpagecontext -> get_parent_context ());
$this -> assertEquals ( array ( $systemcontext -> id => $systemcontext ), $frontpagecontext -> get_parent_contexts ());
$this -> assertEquals ( array ( $frontpagecontext -> id => $frontpagecontext , $systemcontext -> id => $systemcontext ), $frontpagecontext -> get_parent_contexts ( true ));
$this -> assertEquals ( array ( $systemcontext -> id ), $frontpagecontext -> get_parent_context_ids ());
$this -> assertEquals ( array ( $frontpagecontext -> id , $systemcontext -> id ), $frontpagecontext -> get_parent_context_ids ( true ));
2018-06-21 13:23:03 -04:00
$this -> assertEquals ( array ( $systemcontext -> id => $systemcontext -> path ), $frontpagecontext -> get_parent_context_paths ());
$expected = array ( $systemcontext -> id => $systemcontext -> path , $frontpagecontext -> id => $frontpagecontext -> path );
$this -> assertEquals ( $expected , $frontpagecontext -> get_parent_context_paths ( true ));
2013-07-27 10:58:11 +02:00
$this -> assertFalse ( $systemcontext -> get_parent_context ());
2012-03-31 23:51:02 +02:00
$frontpagecontext = context_course :: instance ( $SITE -> id );
$parent = $systemcontext ;
foreach ( $testcategories as $catid ) {
$catcontext = context_coursecat :: instance ( $catid );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $parent , $catcontext -> get_parent_context ());
2012-03-31 23:51:02 +02:00
$parent = $catcontext ;
}
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $frontpagecontext , $frontpagepagecontext -> get_parent_context ());
$this -> assertEquals ( $frontpagecontext , $frontpageblockcontext -> get_parent_context ());
$this -> assertEquals ( $frontpagepagecontext , $frontpagepageblockcontext -> get_parent_context ());
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test $context->get_child_contexts() method.
2012-03-31 23:51:02 +02:00
$children = $systemcontext -> get_child_contexts ();
2012-09-17 12:06:24 +02:00
$this -> resetDebugging ();
2012-03-31 23:51:02 +02:00
$this -> assertEquals ( count ( $children ) + 1 , $DB -> count_records ( 'context' ));
$context = context_coursecat :: instance ( $testcategories [ 3 ]);
$children = $context -> get_child_contexts ();
$countcats = 0 ;
$countcourses = 0 ;
$countblocks = 0 ;
foreach ( $children as $child ) {
if ( $child -> contextlevel == CONTEXT_COURSECAT ) {
$countcats ++ ;
}
if ( $child -> contextlevel == CONTEXT_COURSE ) {
$countcourses ++ ;
}
if ( $child -> contextlevel == CONTEXT_BLOCK ) {
$countblocks ++ ;
}
}
2013-07-27 10:58:11 +02:00
$this -> assertCount ( 8 , $children );
$this -> assertEquals ( 1 , $countcats );
$this -> assertEquals ( 6 , $countcourses );
$this -> assertEquals ( 1 , $countblocks );
2012-03-31 23:51:02 +02:00
$context = context_course :: instance ( $testcourses [ 2 ]);
$children = $context -> get_child_contexts ();
$context = context_module :: instance ( $testpages [ 3 ]);
$children = $context -> get_child_contexts ();
2013-07-27 10:58:11 +02:00
$this -> assertCount ( 1 , $children );
2012-03-31 23:51:02 +02:00
$context = context_block :: instance ( $testblocks [ 1 ]);
$children = $context -> get_child_contexts ();
2013-07-27 10:58:11 +02:00
$this -> assertCount ( 0 , $children );
2012-03-31 23:51:02 +02:00
unset ( $children );
unset ( $countcats );
unset ( $countcourses );
unset ( $countblocks );
2013-07-27 10:58:11 +02:00
// Test context_helper::reset_caches() method.
2012-03-31 23:51:02 +02:00
context_helper :: reset_caches ();
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 0 , context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
context_course :: instance ( $SITE -> id );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 1 , context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test context preloading.
2012-03-31 23:51:02 +02:00
context_helper :: reset_caches ();
$sql = " SELECT " . context_helper :: get_preload_record_columns_sql ( 'c' ) . "
FROM { context } c
WHERE c . contextlevel <> " .CONTEXT_SYSTEM;
$records = $DB -> get_records_sql ( $sql );
$firstrecord = reset ( $records );
$columns = context_helper :: get_preload_record_columns ( 'c' );
$firstrecord = ( array ) $firstrecord ;
$this -> assertSame ( array_keys ( $firstrecord ), array_values ( $columns ));
context_helper :: reset_caches ();
foreach ( $records as $record ) {
context_helper :: preload_from_record ( $record );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( new stdClass (), $record );
2012-03-31 23:51:02 +02:00
}
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( count ( $records ), context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
unset ( $records );
unset ( $columns );
context_helper :: reset_caches ();
context_helper :: preload_course ( $SITE -> id );
2012-11-15 14:30:33 +00:00
$numfrontpagemodules = $DB -> count_records ( 'course_modules' , array ( 'course' => $SITE -> id ));
2016-10-14 14:15:17 +08:00
$this -> assertEquals ( 3 + $numfrontpagemodules , context_inspection :: test_context_cache_size ()); // Depends on number of default blocks.
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test assign_capability(), unassign_capability() functions.
2012-03-31 23:51:02 +02:00
$rc = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontpagecontext -> id , 'roleid' => $allroles [ 'teacher' ], 'capability' => 'moodle/site:accessallgroups' ));
$this -> assertFalse ( $rc );
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $allroles [ 'teacher' ], $frontpagecontext -> id );
$rc = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontpagecontext -> id , 'roleid' => $allroles [ 'teacher' ], 'capability' => 'moodle/site:accessallgroups' ));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( CAP_ALLOW , $rc -> permission );
2012-03-31 23:51:02 +02:00
assign_capability ( 'moodle/site:accessallgroups' , CAP_PREVENT , $allroles [ 'teacher' ], $frontpagecontext -> id );
$rc = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontpagecontext -> id , 'roleid' => $allroles [ 'teacher' ], 'capability' => 'moodle/site:accessallgroups' ));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( CAP_ALLOW , $rc -> permission );
2012-03-31 23:51:02 +02:00
assign_capability ( 'moodle/site:accessallgroups' , CAP_PREVENT , $allroles [ 'teacher' ], $frontpagecontext , true );
$rc = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontpagecontext -> id , 'roleid' => $allroles [ 'teacher' ], 'capability' => 'moodle/site:accessallgroups' ));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( CAP_PREVENT , $rc -> permission );
2012-03-31 23:51:02 +02:00
assign_capability ( 'moodle/site:accessallgroups' , CAP_INHERIT , $allroles [ 'teacher' ], $frontpagecontext );
$rc = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontpagecontext -> id , 'roleid' => $allroles [ 'teacher' ], 'capability' => 'moodle/site:accessallgroups' ));
$this -> assertFalse ( $rc );
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $allroles [ 'teacher' ], $frontpagecontext );
unassign_capability ( 'moodle/site:accessallgroups' , $allroles [ 'teacher' ], $frontpagecontext , true );
$rc = $DB -> get_record ( 'role_capabilities' , array ( 'contextid' => $frontpagecontext -> id , 'roleid' => $allroles [ 'teacher' ], 'capability' => 'moodle/site:accessallgroups' ));
$this -> assertFalse ( $rc );
unassign_capability ( 'moodle/site:accessallgroups' , $allroles [ 'teacher' ], $frontpagecontext -> id , true );
unset ( $rc );
2014-01-24 10:32:21 +11:00
accesslib_clear_all_caches_for_unit_testing (); // Must be done after assign_capability().
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test role_assign(), role_unassign(), role_unassign_all() functions.
2012-03-31 23:51:02 +02:00
$context = context_course :: instance ( $testcourses [ 1 ]);
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 0 , $DB -> count_records ( 'role_assignments' , array ( 'contextid' => $context -> id )));
2012-03-31 23:51:02 +02:00
role_assign ( $allroles [ 'teacher' ], $testusers [ 1 ], $context -> id );
role_assign ( $allroles [ 'teacher' ], $testusers [ 2 ], $context -> id );
role_assign ( $allroles [ 'manager' ], $testusers [ 1 ], $context -> id );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 3 , $DB -> count_records ( 'role_assignments' , array ( 'contextid' => $context -> id )));
2012-03-31 23:51:02 +02:00
role_unassign ( $allroles [ 'teacher' ], $testusers [ 1 ], $context -> id );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 2 , $DB -> count_records ( 'role_assignments' , array ( 'contextid' => $context -> id )));
2012-03-31 23:51:02 +02:00
role_unassign_all ( array ( 'contextid' => $context -> id ));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 0 , $DB -> count_records ( 'role_assignments' , array ( 'contextid' => $context -> id )));
2012-03-31 23:51:02 +02:00
unset ( $context );
2014-01-24 10:32:21 +11:00
accesslib_clear_all_caches_for_unit_testing (); // Just in case.
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends functions.
2012-03-31 23:51:02 +02:00
$adminid = get_admin () -> id ;
$guestid = $CFG -> siteguest ;
2013-07-27 10:58:11 +02:00
// Enrol some users into some courses.
2013-08-21 13:42:30 +08:00
$course1 = $DB -> get_record ( 'course' , array ( 'id' => $testcourses [ 22 ]), '*' , MUST_EXIST );
$course2 = $DB -> get_record ( 'course' , array ( 'id' => $testcourses [ 7 ]), '*' , MUST_EXIST );
2012-03-31 23:51:02 +02:00
$cms = $DB -> get_records ( 'course_modules' , array ( 'course' => $course1 -> id ), 'id' );
$cm1 = reset ( $cms );
$blocks = $DB -> get_records ( 'block_instances' , array ( 'parentcontextid' => context_module :: instance ( $cm1 -> id ) -> id ), 'id' );
$block1 = reset ( $blocks );
$instance1 = $DB -> get_record ( 'enrol' , array ( 'enrol' => 'manual' , 'courseid' => $course1 -> id ));
$instance2 = $DB -> get_record ( 'enrol' , array ( 'enrol' => 'manual' , 'courseid' => $course2 -> id ));
2013-07-27 10:58:11 +02:00
for ( $i = 0 ; $i < 9 ; $i ++ ) {
2012-03-31 23:51:02 +02:00
$manualenrol -> enrol_user ( $instance1 , $testusers [ $i ], $allroles [ 'student' ]);
}
$manualenrol -> enrol_user ( $instance1 , $testusers [ 8 ], $allroles [ 'teacher' ]);
$manualenrol -> enrol_user ( $instance1 , $testusers [ 9 ], $allroles [ 'editingteacher' ]);
2013-07-27 10:58:11 +02:00
for ( $i = 10 ; $i < 15 ; $i ++ ) {
2012-03-31 23:51:02 +02:00
$manualenrol -> enrol_user ( $instance2 , $testusers [ $i ], $allroles [ 'student' ]);
}
$manualenrol -> enrol_user ( $instance2 , $testusers [ 15 ], $allroles [ 'editingteacher' ]);
2013-07-27 10:58:11 +02:00
// Add tons of role assignments - the more the better.
2012-03-31 23:51:02 +02:00
role_assign ( $allroles [ 'coursecreator' ], $testusers [ 11 ], context_coursecat :: instance ( $testcategories [ 2 ]));
role_assign ( $allroles [ 'manager' ], $testusers [ 12 ], context_coursecat :: instance ( $testcategories [ 1 ]));
role_assign ( $allroles [ 'student' ], $testusers [ 9 ], context_module :: instance ( $cm1 -> id ));
role_assign ( $allroles [ 'teacher' ], $testusers [ 8 ], context_module :: instance ( $cm1 -> id ));
role_assign ( $allroles [ 'guest' ], $testusers [ 13 ], context_course :: instance ( $course1 -> id ));
role_assign ( $allroles [ 'teacher' ], $testusers [ 7 ], context_block :: instance ( $block1 -> id ));
role_assign ( $allroles [ 'manager' ], $testusers [ 9 ], context_block :: instance ( $block1 -> id ));
role_assign ( $allroles [ 'editingteacher' ], $testusers [ 9 ], context_course :: instance ( $course1 -> id ));
role_assign ( $allroles [ 'teacher' ], $adminid , context_course :: instance ( $course1 -> id ));
role_assign ( $allroles [ 'editingteacher' ], $adminid , context_block :: instance ( $block1 -> id ));
2013-07-27 10:58:11 +02:00
// Add tons of overrides - the more the better.
2012-03-31 23:51:02 +02:00
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $CFG -> defaultuserroleid , $frontpageblockcontext , true );
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $CFG -> defaultfrontpageroleid , $frontpageblockcontext , true );
assign_capability ( 'moodle/block:view' , CAP_PROHIBIT , $allroles [ 'guest' ], $frontpageblockcontext , true );
assign_capability ( 'block/online_users:viewlist' , CAP_PREVENT , $allroles [ 'user' ], $frontpageblockcontext , true );
assign_capability ( 'block/online_users:viewlist' , CAP_PREVENT , $allroles [ 'student' ], $frontpageblockcontext , true );
assign_capability ( 'moodle/site:accessallgroups' , CAP_PREVENT , $CFG -> defaultuserroleid , $frontpagepagecontext , true );
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $CFG -> defaultfrontpageroleid , $frontpagepagecontext , true );
assign_capability ( 'mod/page:view' , CAP_PREVENT , $allroles [ 'guest' ], $frontpagepagecontext , true );
assign_capability ( 'mod/page:view' , CAP_ALLOW , $allroles [ 'user' ], $frontpagepagecontext , true );
2019-02-28 08:39:20 +08:00
assign_capability ( 'mod/page:view' , CAP_ALLOW , $allroles [ 'student' ], $frontpagepagecontext , true );
2012-03-31 23:51:02 +02:00
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $CFG -> defaultuserroleid , $frontpagecontext , true );
assign_capability ( 'moodle/site:accessallgroups' , CAP_ALLOW , $CFG -> defaultfrontpageroleid , $frontpagecontext , true );
assign_capability ( 'mod/page:view' , CAP_ALLOW , $allroles [ 'guest' ], $frontpagecontext , true );
assign_capability ( 'mod/page:view' , CAP_PROHIBIT , $allroles [ 'user' ], $frontpagecontext , true );
assign_capability ( 'mod/page:view' , CAP_PREVENT , $allroles [ 'guest' ], $systemcontext , true );
2016-12-07 15:45:10 +13:00
// Prepare for prohibit test.
role_assign ( $allroles [ 'editingteacher' ], $testusers [ 19 ], context_system :: instance ());
role_assign ( $allroles [ 'teacher' ], $testusers [ 19 ], context_course :: instance ( $testcourses [ 17 ]));
role_assign ( $allroles [ 'editingteacher' ], $testusers [ 19 ], context_course :: instance ( $testcourses [ 17 ]));
assign_capability ( 'moodle/course:update' , CAP_PROHIBIT , $allroles [ 'teacher' ], context_course :: instance ( $testcourses [ 17 ]), true );
2014-01-24 10:32:21 +11:00
accesslib_clear_all_caches_for_unit_testing (); /// Must be done after assign_capability().
2012-03-31 23:51:02 +02:00
// Extra tests for guests and not-logged-in users because they can not be verified by cross checking
2013-07-27 10:58:11 +02:00
// with get_users_by_capability() where they are ignored.
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( has_capability ( 'moodle/block:view' , $frontpageblockcontext , $guestid ));
$this -> assertFalse ( has_capability ( 'mod/page:view' , $frontpagepagecontext , $guestid ));
$this -> assertTrue ( has_capability ( 'mod/page:view' , $frontpagecontext , $guestid ));
$this -> assertFalse ( has_capability ( 'mod/page:view' , $systemcontext , $guestid ));
$this -> assertFalse ( has_capability ( 'moodle/block:view' , $frontpageblockcontext , 0 ));
$this -> assertFalse ( has_capability ( 'mod/page:view' , $frontpagepagecontext , 0 ));
$this -> assertTrue ( has_capability ( 'mod/page:view' , $frontpagecontext , 0 ));
$this -> assertFalse ( has_capability ( 'mod/page:view' , $systemcontext , 0 ));
$this -> assertFalse ( has_capability ( 'moodle/course:create' , $systemcontext , $testusers [ 11 ]));
$this -> assertTrue ( has_capability ( 'moodle/course:create' , context_coursecat :: instance ( $testcategories [ 2 ]), $testusers [ 11 ]));
$this -> assertFalse ( has_capability ( 'moodle/course:create' , context_course :: instance ( $testcourses [ 1 ]), $testusers [ 11 ]));
$this -> assertTrue ( has_capability ( 'moodle/course:create' , context_course :: instance ( $testcourses [ 19 ]), $testusers [ 11 ]));
$this -> assertFalse ( has_capability ( 'moodle/course:update' , context_course :: instance ( $testcourses [ 1 ]), $testusers [ 9 ]));
$this -> assertFalse ( has_capability ( 'moodle/course:update' , context_course :: instance ( $testcourses [ 19 ]), $testusers [ 9 ]));
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $systemcontext , $testusers [ 9 ]));
2016-12-07 15:45:10 +13:00
// Test prohibits.
$this -> assertTrue ( has_capability ( 'moodle/course:update' , context_system :: instance (), $testusers [ 19 ]));
$ids = get_users_by_capability ( context_system :: instance (), 'moodle/course:update' , 'u.id' );
$this -> assertArrayHasKey ( $testusers [ 19 ], $ids );
$this -> assertFalse ( has_capability ( 'moodle/course:update' , context_course :: instance ( $testcourses [ 17 ]), $testusers [ 19 ]));
$ids = get_users_by_capability ( context_course :: instance ( $testcourses [ 17 ]), 'moodle/course:update' , 'u.id' );
$this -> assertArrayNotHasKey ( $testusers [ 19 ], $ids );
2013-07-27 10:58:11 +02:00
// Test the list of enrolled users.
2012-03-31 23:51:02 +02:00
$coursecontext = context_course :: instance ( $course1 -> id );
$enrolled = get_enrolled_users ( $coursecontext );
2013-07-27 10:58:11 +02:00
$this -> assertCount ( 10 , $enrolled );
for ( $i = 0 ; $i < 10 ; $i ++ ) {
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( isset ( $enrolled [ $testusers [ $i ]]));
}
$enrolled = get_enrolled_users ( $coursecontext , 'moodle/course:update' );
2013-07-27 10:58:11 +02:00
$this -> assertCount ( 1 , $enrolled );
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( isset ( $enrolled [ $testusers [ 9 ]]));
unset ( $enrolled );
2013-07-27 10:58:11 +02:00
// Role switching.
2012-03-31 23:51:02 +02:00
$userid = $testusers [ 9 ];
$USER = $DB -> get_record ( 'user' , array ( 'id' => $userid ));
load_all_capabilities ();
$coursecontext = context_course :: instance ( $course1 -> id );
$this -> assertTrue ( has_capability ( 'moodle/course:update' , $coursecontext ));
$this -> assertFalse ( is_role_switched ( $course1 -> id ));
role_switch ( $allroles [ 'student' ], $coursecontext );
$this -> assertTrue ( is_role_switched ( $course1 -> id ));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $allroles [ 'student' ], $USER -> access [ 'rsw' ][ $coursecontext -> path ]);
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $coursecontext ));
reload_all_capabilities ();
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $coursecontext ));
role_switch ( 0 , $coursecontext );
$this -> assertTrue ( has_capability ( 'moodle/course:update' , $coursecontext ));
$userid = $adminid ;
$USER = $DB -> get_record ( 'user' , array ( 'id' => $userid ));
load_all_capabilities ();
$coursecontext = context_course :: instance ( $course1 -> id );
$blockcontext = context_block :: instance ( $block1 -> id );
$this -> assertTrue ( has_capability ( 'moodle/course:update' , $blockcontext ));
role_switch ( $allroles [ 'student' ], $coursecontext );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $allroles [ 'student' ], $USER -> access [ 'rsw' ][ $coursecontext -> path ]);
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $blockcontext ));
reload_all_capabilities ();
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $blockcontext ));
load_all_capabilities ();
$this -> assertTrue ( has_capability ( 'moodle/course:update' , $blockcontext ));
2013-07-27 10:58:11 +02:00
// Temp course role for enrol.
$DB -> delete_records ( 'cache_flags' , array ()); // This prevents problem with dirty contexts immediately resetting the temp role - this is a known problem...
2012-03-31 23:51:02 +02:00
$userid = $testusers [ 5 ];
$roleid = $allroles [ 'editingteacher' ];
$USER = $DB -> get_record ( 'user' , array ( 'id' => $userid ));
load_all_capabilities ();
$coursecontext = context_course :: instance ( $course1 -> id );
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $coursecontext ));
$this -> assertFalse ( isset ( $USER -> access [ 'ra' ][ $coursecontext -> path ][ $roleid ]));
load_temp_course_role ( $coursecontext , $roleid );
$this -> assertEquals ( $USER -> access [ 'ra' ][ $coursecontext -> path ][ $roleid ], $roleid );
$this -> assertTrue ( has_capability ( 'moodle/course:update' , $coursecontext ));
remove_temp_course_roles ( $coursecontext );
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $coursecontext , $userid ));
load_temp_course_role ( $coursecontext , $roleid );
reload_all_capabilities ();
$this -> assertFalse ( has_capability ( 'moodle/course:update' , $coursecontext , $userid ));
$USER = new stdClass ();
$USER -> id = 0 ;
// Now cross check has_capability() with get_users_by_capability(), each using different code paths,
// they have to be kept in sync, usually only one of them breaks, so we know when something is wrong,
2013-07-27 10:58:11 +02:00
// at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users).
2012-03-31 23:51:02 +02:00
$contexts = $DB -> get_records ( 'context' , array (), 'id' );
$contexts = array_values ( $contexts );
$capabilities = $DB -> get_records ( 'capabilities' , array (), 'id' );
$capabilities = array_values ( $capabilities );
$roles = array ( $allroles [ 'guest' ], $allroles [ 'user' ], $allroles [ 'teacher' ], $allroles [ 'editingteacher' ], $allroles [ 'coursecreator' ], $allroles [ 'manager' ]);
2012-04-03 11:12:52 +02:00
$userids = array_values ( $testusers );
$userids [] = get_admin () -> id ;
2012-03-31 23:51:02 +02:00
2012-04-03 11:12:52 +02:00
if ( ! PHPUNIT_LONGTEST ) {
$contexts = array_slice ( $contexts , 0 , 10 );
$capabilities = array_slice ( $capabilities , 0 , 5 );
$userids = array_slice ( $userids , 0 , 5 );
}
2013-07-27 10:58:11 +02:00
foreach ( $userids as $userid ) { // No guest or deleted.
// Each user gets 0-10 random roles.
2012-04-03 11:12:52 +02:00
$rcount = rand ( 0 , 10 );
2013-07-27 10:58:11 +02:00
for ( $j = 0 ; $j < $rcount ; $j ++ ) {
2012-03-31 23:51:02 +02:00
$roleid = $roles [ rand ( 0 , count ( $roles ) - 1 )];
$contextid = $contexts [ rand ( 0 , count ( $contexts ) - 1 )] -> id ;
2012-04-03 11:12:52 +02:00
role_assign ( $roleid , $userid , $contextid );
2012-03-31 23:51:02 +02:00
}
}
2012-04-03 11:12:52 +02:00
$permissions = array ( CAP_ALLOW , CAP_PREVENT , CAP_INHERIT , CAP_PREVENT );
$maxoverrides = count ( $contexts ) * 10 ;
2013-07-27 10:58:11 +02:00
for ( $j = 0 ; $j < $maxoverrides ; $j ++ ) {
2012-04-03 11:12:52 +02:00
$roleid = $roles [ rand ( 0 , count ( $roles ) - 1 )];
$contextid = $contexts [ rand ( 0 , count ( $contexts ) - 1 )] -> id ;
2013-07-27 10:58:11 +02:00
$permission = $permissions [ rand ( 0 , count ( $permissions ) - 1 )];
2012-04-03 11:12:52 +02:00
$capname = $capabilities [ rand ( 0 , count ( $capabilities ) - 1 )] -> name ;
assign_capability ( $capname , $permission , $roleid , $contextid , true );
}
unset ( $permissions );
unset ( $roles );
2014-01-24 10:32:21 +11:00
accesslib_clear_all_caches_for_unit_testing (); // must be done after assign_capability().
2012-04-03 11:12:52 +02:00
// Test time - let's set up some real user, just in case the logic for USER affects the others...
$USER = $DB -> get_record ( 'user' , array ( 'id' => $testusers [ 3 ]));
load_all_capabilities ();
$userids [] = $CFG -> siteguest ;
2013-07-27 10:58:11 +02:00
$userids [] = 0 ; // Not-logged-in user.
$userids [] = - 1 ; // Non-existent user.
2012-04-03 11:12:52 +02:00
2012-03-31 23:51:02 +02:00
foreach ( $contexts as $crecord ) {
$context = context :: instance_by_id ( $crecord -> id );
if ( $coursecontext = $context -> get_course_context ( false )) {
$enrolled = get_enrolled_users ( $context );
} else {
$enrolled = array ();
}
foreach ( $capabilities as $cap ) {
$allowed = get_users_by_capability ( $context , $cap -> name , 'u.id, u.username' );
if ( $enrolled ) {
$enrolledwithcap = get_enrolled_users ( $context , $cap -> name );
} else {
$enrolledwithcap = array ();
}
2012-04-03 11:12:52 +02:00
foreach ( $userids as $userid ) {
2012-03-31 23:51:02 +02:00
if ( $userid == 0 or isguestuser ( $userid )) {
if ( $userid == 0 ) {
$CFG -> forcelogin = true ;
$this -> assertFalse ( has_capability ( $cap -> name , $context , $userid ));
unset ( $CFG -> forcelogin );
}
if (( $cap -> captype === 'write' ) or ( $cap -> riskbitmask & ( RISK_XSS | RISK_CONFIG | RISK_DATALOSS ))) {
$this -> assertFalse ( has_capability ( $cap -> name , $context , $userid ));
}
$this -> assertFalse ( isset ( $allowed [ $userid ]));
} else {
if ( is_siteadmin ( $userid )) {
$this -> assertTrue ( has_capability ( $cap -> name , $context , $userid , true ));
}
$hascap = has_capability ( $cap -> name , $context , $userid , false );
$this -> assertSame ( $hascap , isset ( $allowed [ $userid ]), " Capability result mismatch user: $userid , context: $context->id , $cap->name , hascap: " . ( int ) $hascap . " " );
if ( isset ( $enrolled [ $userid ])) {
$this -> assertSame ( isset ( $allowed [ $userid ]), isset ( $enrolledwithcap [ $userid ]), " Enrolment with capability result mismatch user: $userid , context: $context->id , $cap->name , hascap: " . ( int ) $hascap . " " );
}
}
}
}
}
2013-07-27 10:58:11 +02:00
// Back to nobody.
2012-03-31 23:51:02 +02:00
$USER = new stdClass ();
$USER -> id = 0 ;
unset ( $contexts );
2012-04-03 11:12:52 +02:00
unset ( $userids );
2012-03-31 23:51:02 +02:00
unset ( $capabilities );
2013-07-27 10:58:11 +02:00
// Now let's do all the remaining tests that break our carefully prepared fake site.
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test $context->mark_dirty() method.
2012-03-31 23:51:02 +02:00
$DB -> delete_records ( 'cache_flags' , array ());
accesslib_clear_all_caches ( false );
$systemcontext -> mark_dirty ();
$dirty = get_cache_flags ( 'accesslib/dirtycontexts' , time () - 2 );
$this -> assertTrue ( isset ( $dirty [ $systemcontext -> path ]));
$this -> assertTrue ( isset ( $ACCESSLIB_PRIVATE -> dirtycontexts [ $systemcontext -> path ]));
2013-07-27 10:58:11 +02:00
// Test $context->reload_if_dirty() method.
2012-03-31 23:51:02 +02:00
$DB -> delete_records ( 'cache_flags' , array ());
accesslib_clear_all_caches ( false );
load_all_capabilities ();
$context = context_course :: instance ( $testcourses [ 2 ]);
$page = $DB -> get_record ( 'page' , array ( 'course' => $testcourses [ 2 ]));
2012-11-15 14:30:33 +00:00
$pagecm = get_coursemodule_from_instance ( 'page' , $page -> id );
$pagecontext = context_module :: instance ( $pagecm -> id );
2012-03-31 23:51:02 +02:00
$context -> mark_dirty ();
$this -> assertTrue ( isset ( $ACCESSLIB_PRIVATE -> dirtycontexts [ $context -> path ]));
$USER -> access [ 'test' ] = true ;
$context -> reload_if_dirty ();
$this -> assertFalse ( isset ( $USER -> access [ 'test' ]));
$context -> mark_dirty ();
$this -> assertTrue ( isset ( $ACCESSLIB_PRIVATE -> dirtycontexts [ $context -> path ]));
$USER -> access [ 'test' ] = true ;
$pagecontext -> reload_if_dirty ();
$this -> assertFalse ( isset ( $USER -> access [ 'test' ]));
2013-07-27 10:58:11 +02:00
// Test context_helper::build_all_paths() method.
2012-03-31 23:51:02 +02:00
$oldcontexts = $DB -> get_records ( 'context' , array (), 'id' );
2013-07-27 10:58:11 +02:00
$DB -> set_field_select ( 'context' , 'path' , null , " contextlevel <> " . CONTEXT_SYSTEM );
2012-03-31 23:51:02 +02:00
$DB -> set_field_select ( 'context' , 'depth' , 0 , " contextlevel <> " . CONTEXT_SYSTEM );
context_helper :: build_all_paths ();
$newcontexts = $DB -> get_records ( 'context' , array (), 'id' );
$this -> assertEquals ( $oldcontexts , $newcontexts );
unset ( $oldcontexts );
unset ( $newcontexts );
2013-07-27 10:58:11 +02:00
// Test $context->reset_paths() method.
2012-03-31 23:51:02 +02:00
$context = context_course :: instance ( $testcourses [ 2 ]);
$children = $context -> get_child_contexts ();
$context -> reset_paths ( false );
2013-07-27 10:58:11 +02:00
$this -> assertNull ( $DB -> get_field ( 'context' , 'path' , array ( 'id' => $context -> id )));
$this -> assertEquals ( 0 , $DB -> get_field ( 'context' , 'depth' , array ( 'id' => $context -> id )));
2012-03-31 23:51:02 +02:00
foreach ( $children as $child ) {
2013-07-27 10:58:11 +02:00
$this -> assertNull ( $DB -> get_field ( 'context' , 'path' , array ( 'id' => $child -> id )));
$this -> assertEquals ( 0 , $DB -> get_field ( 'context' , 'depth' , array ( 'id' => $child -> id )));
2012-03-31 23:51:02 +02:00
}
$this -> assertEquals ( count ( $children ) + 1 , $DB -> count_records ( 'context' , array ( 'depth' => 0 )));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( count ( $children ) + 1 , $DB -> count_records ( 'context' , array ( 'path' => null )));
2012-03-31 23:51:02 +02:00
$context = context_course :: instance ( $testcourses [ 2 ]);
$context -> reset_paths ( true );
$context = context_course :: instance ( $testcourses [ 2 ]);
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $context -> path , $DB -> get_field ( 'context' , 'path' , array ( 'id' => $context -> id )));
$this -> assertSame ( $context -> depth , $DB -> get_field ( 'context' , 'depth' , array ( 'id' => $context -> id )));
2012-03-31 23:51:02 +02:00
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'depth' => 0 )));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'path' => null )));
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test $context->update_moved() method.
2012-03-31 23:51:02 +02:00
accesslib_clear_all_caches ( false );
$DB -> delete_records ( 'cache_flags' , array ());
$course = $DB -> get_record ( 'course' , array ( 'id' => $testcourses [ 0 ]));
$context = context_course :: instance ( $course -> id );
$oldpath = $context -> path ;
$miscid = $DB -> get_field_sql ( " SELECT MIN(id) FROM { course_categories} " );
$categorycontext = context_coursecat :: instance ( $miscid );
$course -> category = $miscid ;
2013-08-21 15:11:59 +12:00
$DB -> update_record ( 'course' , $course );
2012-03-31 23:51:02 +02:00
$context -> update_moved ( $categorycontext );
$context = context_course :: instance ( $course -> id );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $categorycontext , $context -> get_parent_context ());
2012-03-31 23:51:02 +02:00
$dirty = get_cache_flags ( 'accesslib/dirtycontexts' , time () - 2 );
2018-06-05 15:13:02 -04:00
$this -> assertFalse ( isset ( $dirty [ $oldpath ]));
2012-03-31 23:51:02 +02:00
$this -> assertTrue ( isset ( $dirty [ $context -> path ]));
2013-07-27 10:58:11 +02:00
// Test $context->delete_content() method.
2012-03-31 23:51:02 +02:00
context_helper :: reset_caches ();
$context = context_module :: instance ( $testpages [ 3 ]);
$this -> assertTrue ( $DB -> record_exists ( 'context' , array ( 'id' => $context -> id )));
$this -> assertEquals ( 1 , $DB -> count_records ( 'block_instances' , array ( 'parentcontextid' => $context -> id )));
$context -> delete_content ();
$this -> assertTrue ( $DB -> record_exists ( 'context' , array ( 'id' => $context -> id )));
$this -> assertEquals ( 0 , $DB -> count_records ( 'block_instances' , array ( 'parentcontextid' => $context -> id )));
2013-07-27 10:58:11 +02:00
// Test $context->delete() method.
2012-03-31 23:51:02 +02:00
context_helper :: reset_caches ();
$context = context_module :: instance ( $testpages [ 4 ]);
$this -> assertTrue ( $DB -> record_exists ( 'context' , array ( 'id' => $context -> id )));
$this -> assertEquals ( 1 , $DB -> count_records ( 'block_instances' , array ( 'parentcontextid' => $context -> id )));
$bi = $DB -> get_record ( 'block_instances' , array ( 'parentcontextid' => $context -> id ));
$bicontext = context_block :: instance ( $bi -> id );
$DB -> delete_records ( 'cache_flags' , array ());
2013-07-27 10:58:11 +02:00
$context -> delete (); // Should delete also linked blocks.
2012-03-31 23:51:02 +02:00
$dirty = get_cache_flags ( 'accesslib/dirtycontexts' , time () - 2 );
2018-06-05 15:13:02 -04:00
$this -> assertFalse ( isset ( $dirty [ $context -> path ]));
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( $DB -> record_exists ( 'context' , array ( 'id' => $context -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'context' , array ( 'id' => $bicontext -> id )));
$this -> assertFalse ( $DB -> record_exists ( 'context' , array ( 'contextlevel' => CONTEXT_MODULE , 'instanceid' => $testpages [ 4 ])));
$this -> assertFalse ( $DB -> record_exists ( 'context' , array ( 'contextlevel' => CONTEXT_BLOCK , 'instanceid' => $bi -> id )));
$this -> assertEquals ( 0 , $DB -> count_records ( 'block_instances' , array ( 'parentcontextid' => $context -> id )));
context_module :: instance ( $testpages [ 4 ]);
2013-07-27 10:58:11 +02:00
// Test context_helper::delete_instance() method.
2012-03-31 23:51:02 +02:00
context_helper :: reset_caches ();
$lastcourse = array_pop ( $testcourses );
$this -> assertTrue ( $DB -> record_exists ( 'context' , array ( 'contextlevel' => CONTEXT_COURSE , 'instanceid' => $lastcourse )));
$coursecontext = context_course :: instance ( $lastcourse );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 1 , context_inspection :: test_context_cache_size ());
$this -> assertNotEquals ( CONTEXT_COURSE , $coursecontext -> instanceid );
2012-03-31 23:51:02 +02:00
$DB -> delete_records ( 'cache_flags' , array ());
context_helper :: delete_instance ( CONTEXT_COURSE , $lastcourse );
$dirty = get_cache_flags ( 'accesslib/dirtycontexts' , time () - 2 );
2018-06-05 15:13:02 -04:00
$this -> assertFalse ( isset ( $dirty [ $coursecontext -> path ]));
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 0 , context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
$this -> assertFalse ( $DB -> record_exists ( 'context' , array ( 'contextlevel' => CONTEXT_COURSE , 'instanceid' => $lastcourse )));
context_course :: instance ( $lastcourse );
2013-07-27 10:58:11 +02:00
// Test context_helper::create_instances() method.
2012-03-31 23:51:02 +02:00
$prevcount = $DB -> count_records ( 'context' );
$DB -> delete_records ( 'context' , array ( 'contextlevel' => CONTEXT_BLOCK ));
context_helper :: create_instances ( null , true );
$this -> assertSame ( $DB -> count_records ( 'context' ), $prevcount );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'depth' => 0 )));
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'path' => null )));
2012-03-31 23:51:02 +02:00
$DB -> delete_records ( 'context' , array ( 'contextlevel' => CONTEXT_BLOCK ));
$DB -> delete_records ( 'block_instances' , array ());
$prevcount = $DB -> count_records ( 'context' );
$DB -> delete_records_select ( 'context' , 'contextlevel <> ' . CONTEXT_SYSTEM );
context_helper :: create_instances ( null , true );
2013-07-27 10:58:11 +02:00
$this -> assertSame ( $prevcount , $DB -> count_records ( 'context' ));
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'depth' => 0 )));
$this -> assertEquals ( 0 , $DB -> count_records ( 'context' , array ( 'path' => null )));
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test context_helper::cleanup_instances() method.
2012-03-31 23:51:02 +02:00
$lastcourse = $DB -> get_field_sql ( " SELECT MAX(id) FROM { course} " );
$DB -> delete_records ( 'course' , array ( 'id' => $lastcourse ));
$lastcategory = $DB -> get_field_sql ( " SELECT MAX(id) FROM { course_categories} " );
$DB -> delete_records ( 'course_categories' , array ( 'id' => $lastcategory ));
$lastuser = $DB -> get_field_sql ( " SELECT MAX(id) FROM { user} WHERE deleted=0 " );
$DB -> delete_records ( 'user' , array ( 'id' => $lastuser ));
$DB -> delete_records ( 'block_instances' , array ( 'parentcontextid' => $frontpagepagecontext -> id ));
$DB -> delete_records ( 'course_modules' , array ( 'id' => $frontpagepagecontext -> instanceid ));
context_helper :: cleanup_instances ();
2013-07-27 10:58:11 +02:00
$count = 1 ; // System.
2012-03-31 23:51:02 +02:00
$count += $DB -> count_records ( 'user' , array ( 'deleted' => 0 ));
$count += $DB -> count_records ( 'course_categories' );
$count += $DB -> count_records ( 'course' );
$count += $DB -> count_records ( 'course_modules' );
$count += $DB -> count_records ( 'block_instances' );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $count , $DB -> count_records ( 'context' ));
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
// Test context cache size restrictions.
2012-03-31 23:51:02 +02:00
$testusers = array ();
for ( $i = 0 ; $i < CONTEXT_CACHE_MAX_SIZE + 100 ; $i ++ ) {
$user = $generator -> create_user ();
$testusers [ $i ] = $user -> id ;
}
context_helper :: create_instances ( null , true );
context_helper :: reset_caches ();
for ( $i = 0 ; $i < CONTEXT_CACHE_MAX_SIZE + 100 ; $i ++ ) {
context_user :: instance ( $testusers [ $i ]);
if ( $i == CONTEXT_CACHE_MAX_SIZE - 1 ) {
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( CONTEXT_CACHE_MAX_SIZE , context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
} else if ( $i == CONTEXT_CACHE_MAX_SIZE ) {
2013-07-27 10:58:11 +02:00
// Once the limit is reached roughly 1/3 of records should be removed from cache.
$this -> assertEquals (( int ) ceil ( CONTEXT_CACHE_MAX_SIZE * ( 2 / 3 ) + 101 ), context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
}
}
2013-07-27 10:58:11 +02:00
// We keep the first 100 cached.
2012-03-31 23:51:02 +02:00
$prevsize = context_inspection :: test_context_cache_size ();
for ( $i = 0 ; $i < 100 ; $i ++ ) {
context_user :: instance ( $testusers [ $i ]);
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $prevsize , context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
}
context_user :: instance ( $testusers [ 102 ]);
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $prevsize + 1 , context_inspection :: test_context_cache_size ());
2012-03-31 23:51:02 +02:00
unset ( $testusers );
2013-07-27 10:58:11 +02:00
// Test basic test of legacy functions.
// Note: watch out, the fake site might be pretty borked already.
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( get_system_context (), context_system :: instance ());
2015-06-29 13:03:50 +05:30
$this -> assertDebuggingCalled ( 'get_system_context() is deprecated, please use context_system::instance() instead.' , DEBUG_DEVELOPER );
2012-03-31 23:51:02 +02:00
2013-07-27 10:58:11 +02:00
foreach ( $DB -> get_records ( 'context' ) as $contextid => $record ) {
2012-03-31 23:51:02 +02:00
$context = context :: instance_by_id ( $contextid );
2013-07-27 10:58:11 +02:00
$this -> assertEquals ( $context , get_context_instance ( $record -> contextlevel , $record -> instanceid ));
2015-06-29 13:03:50 +05:30
$this -> assertDebuggingCalled ( 'get_context_instance() is deprecated, please use context_xxxx::instance() instead.' , DEBUG_DEVELOPER );
2012-03-31 23:51:02 +02:00
}
2013-07-02 15:08:14 +08:00
// Make sure a debugging is thrown.
get_context_instance ( $record -> contextlevel , $record -> instanceid );
2013-07-02 21:40:16 +02:00
$this -> assertDebuggingCalled ( 'get_context_instance() is deprecated, please use context_xxxx::instance() instead.' , DEBUG_DEVELOPER );
2013-07-03 14:32:22 +08:00
get_system_context ();
$this -> assertDebuggingCalled ( 'get_system_context() is deprecated, please use context_system::instance() instead.' , DEBUG_DEVELOPER );
2012-03-31 23:51:02 +02:00
}
2012-04-19 08:47:28 +02:00
2018-10-30 12:00:12 +00:00
/**
* Helper that verifies a list of capabilities , as returned by
* $context -> get_capabilities () contains certain capabilities .
*
* @ param array $expected a list of capability names
* @ param array $actual a list of capability info from $context -> get_capabilities () .
*/
protected function assert_capability_list_contains ( $expected , $actual ) {
$actualnames = [];
foreach ( $actual as $cap ) {
$actualnames [ $cap -> name ] = $cap -> name ;
}
$this -> assertArraySubset ( array_combine ( $expected , $expected ), $actualnames );
}
/**
* Test that context_system :: get_capabilities returns capabilities relevant to all modules .
*/
public function test_context_module_caps_returned_by_get_capabilities_in_sys_context () {
$actual = context_system :: instance () -> get_capabilities ();
// Just test a few representative capabilities.
2018-11-05 12:44:03 +00:00
$expectedcapabilities = [ 'moodle/site:accessallgroups' , 'moodle/site:viewfullnames' ,
'repository/upload:view' , 'atto/recordrtc:recordaudio' ];
2018-10-30 12:00:12 +00:00
$this -> assert_capability_list_contains ( $expectedcapabilities , $actual );
}
/**
* Test that context_coursecat :: get_capabilities returns capabilities relevant to all modules .
*/
public function test_context_module_caps_returned_by_get_capabilities_in_course_cat_context () {
$this -> resetAfterTest ( true );
$generator = $this -> getDataGenerator ();
$cat = $generator -> create_category ();
$actual = context_coursecat :: instance ( $cat -> id ) -> get_capabilities ();
// Just test a few representative capabilities.
2018-11-05 12:44:03 +00:00
$expectedcapabilities = [ 'moodle/site:accessallgroups' , 'moodle/site:viewfullnames' ,
'repository/upload:view' , 'atto/recordrtc:recordaudio' ];
2018-10-30 12:00:12 +00:00
$this -> assert_capability_list_contains ( $expectedcapabilities , $actual );
}
/**
* Test that context_course :: get_capabilities returns capabilities relevant to all modules .
*/
public function test_context_module_caps_returned_by_get_capabilities_in_course_context () {
$this -> resetAfterTest ( true );
$generator = $this -> getDataGenerator ();
$cat = $generator -> create_category ();
$course = $generator -> create_course ([ 'category' => $cat -> id ]);
$actual = context_course :: instance ( $course -> id ) -> get_capabilities ();
// Just test a few representative capabilities.
2018-11-05 12:44:03 +00:00
$expectedcapabilities = [ 'moodle/site:accessallgroups' , 'moodle/site:viewfullnames' ,
'repository/upload:view' , 'atto/recordrtc:recordaudio' ];
2018-10-30 12:00:12 +00:00
$this -> assert_capability_list_contains ( $expectedcapabilities , $actual );
}
/**
* Test that context_module :: get_capabilities returns capabilities relevant to all modules .
*/
public function test_context_module_caps_returned_by_get_capabilities_mod_context () {
$this -> resetAfterTest ( true );
$generator = $this -> getDataGenerator ();
$cat = $generator -> create_category ();
$course = $generator -> create_course ([ 'category' => $cat -> id ]);
$page = $generator -> create_module ( 'page' , [ 'course' => $course -> id ]);
$actual = context_module :: instance ( $page -> cmid ) -> get_capabilities ();
// Just test a few representative capabilities.
2018-11-05 12:44:03 +00:00
$expectedcapabilities = [ 'moodle/site:accessallgroups' , 'moodle/site:viewfullnames' ,
'repository/upload:view' , 'atto/recordrtc:recordaudio' ];
2018-10-30 12:00:12 +00:00
$this -> assert_capability_list_contains ( $expectedcapabilities , $actual );
}
2012-05-16 17:24:17 +02:00
/**
* Test updating of role capabilities during upgrade
*/
2012-04-19 08:47:28 +02:00
public function test_update_capabilities () {
global $DB , $SITE ;
$this -> resetAfterTest ( true );
$froncontext = context_course :: instance ( $SITE -> id );
$student = $DB -> get_record ( 'role' , array ( 'archetype' => 'student' ));
$teacher = $DB -> get_record ( 'role' , array ( 'archetype' => 'teacher' ));
$existingcaps = $DB -> get_records ( 'capabilities' , array (), 'id' , 'name, captype, contextlevel, component, riskbitmask' );
2013-07-27 10:58:11 +02:00
$this -> assertFalse ( isset ( $existingcaps [ 'moodle/site:restore' ])); // Moved to new 'moodle/restore:restorecourse'.
$this -> assertTrue ( isset ( $existingcaps [ 'moodle/restore:restorecourse' ])); // New cap from 'moodle/site:restore'.
$this -> assertTrue ( isset ( $existingcaps [ 'moodle/site:sendmessage' ])); // New capability.
2012-04-19 08:47:28 +02:00
$this -> assertTrue ( isset ( $existingcaps [ 'moodle/backup:backupcourse' ]));
2013-07-27 10:58:11 +02:00
$this -> assertTrue ( isset ( $existingcaps [ 'moodle/backup:backupsection' ])); // Cloned from 'moodle/backup:backupcourse'.
$this -> assertTrue ( isset ( $existingcaps [ 'moodle/site:approvecourse' ])); // Updated bitmask.
2012-04-19 08:47:28 +02:00
$this -> assertTrue ( isset ( $existingcaps [ 'moodle/course:manageactivities' ]));
2013-07-27 10:58:11 +02:00
$this -> assertTrue ( isset ( $existingcaps [ 'mod/page:addinstance' ])); // Cloned from core 'moodle/course:manageactivities'.
2012-04-19 08:47:28 +02:00
2013-07-27 10:58:11 +02:00
// Fake state before upgrade.
2012-04-19 08:47:28 +02:00
$DB -> set_field ( 'capabilities' , 'name' , 'moodle/site:restore' , array ( 'name' => 'moodle/restore:restorecourse' ));
$DB -> set_field ( 'role_capabilities' , 'capability' , 'moodle/site:restore' , array ( 'capability' => 'moodle/restore:restorecourse' ));
assign_capability ( 'moodle/site:restore' , CAP_PROHIBIT , $teacher -> id , $froncontext -> id , true );
$perms1 = array_values ( $DB -> get_records ( 'role_capabilities' , array ( 'capability' => 'moodle/site:restore' , 'roleid' => $teacher -> id ), 'contextid, permission' , 'contextid, permission' ));
$DB -> delete_records ( 'role_capabilities' , array ( 'capability' => 'moodle/site:sendmessage' ));
$DB -> delete_records ( 'capabilities' , array ( 'name' => 'moodle/site:sendmessage' ));
$DB -> delete_records ( 'role_capabilities' , array ( 'capability' => 'moodle/backup:backupsection' ));
$DB -> delete_records ( 'capabilities' , array ( 'name' => 'moodle/backup:backupsection' ));
assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $student -> id , $froncontext -> id , true );
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $teacher -> id , $froncontext -> id , true );
$DB -> set_field ( 'capabilities' , 'riskbitmask' , 0 , array ( 'name' => 'moodle/site:approvecourse' ));
$DB -> delete_records ( 'role_capabilities' , array ( 'capability' => 'mod/page:addinstance' ));
$DB -> delete_records ( 'capabilities' , array ( 'name' => 'mod/page:addinstance' ));
assign_capability ( 'moodle/course:manageactivities' , CAP_PROHIBIT , $student -> id , $froncontext -> id , true );
assign_capability ( 'moodle/course:manageactivities' , CAP_ALLOW , $teacher -> id , $froncontext -> id , true );
2013-07-27 10:58:11 +02:00
// Execute core.
2012-04-19 08:47:28 +02:00
update_capabilities ( 'moodle' );
2013-07-27 10:58:11 +02:00
// Only core should be upgraded.
2012-04-19 08:47:28 +02:00
$caps = $DB -> get_records ( 'capabilities' , array (), 'id' , 'name, captype, contextlevel, component, riskbitmask' );
$this -> assertFalse ( isset ( $existingcaps [ 'moodle/site:restore' ]));
$this -> assertTrue ( isset ( $caps [ 'moodle/restore:restorecourse' ]));
$this -> assertEquals ( $existingcaps [ 'moodle/restore:restorecourse' ], $caps [ 'moodle/restore:restorecourse' ]);
$perms2 = array_values ( $DB -> get_records ( 'role_capabilities' , array ( 'capability' => 'moodle/restore:restorecourse' , 'roleid' => $teacher -> id ), 'contextid, permission' , 'contextid, permission' ));
$this -> assertEquals ( $perms1 , $perms2 );
$this -> assertTrue ( isset ( $caps [ 'moodle/site:sendmessage' ]));
$this -> assertEquals ( $existingcaps [ 'moodle/site:sendmessage' ], $caps [ 'moodle/site:sendmessage' ]);
$this -> assertTrue ( isset ( $caps [ 'moodle/backup:backupsection' ]));
$this -> assertEquals ( $existingcaps [ 'moodle/backup:backupsection' ], $caps [ 'moodle/backup:backupsection' ]);
$roles = $DB -> get_records_sql ( 'SELECT DISTINCT roleid AS id FROM {role_capabilities} WHERE capability=? OR capability=?' , array ( 'moodle/backup:backupcourse' , 'moodle/backup:backupsection' ));
foreach ( $roles as $role ) {
$perms1 = array_values ( $DB -> get_records ( 'role_capabilities' , array ( 'capability' => 'moodle/backup:backupcourse' , 'roleid' => $role -> id ), 'contextid, permission' , 'contextid, permission' ));
$perms2 = array_values ( $DB -> get_records ( 'role_capabilities' , array ( 'capability' => 'moodle/backup:backupsection' , 'roleid' => $role -> id ), 'contextid, permission' , 'contextid, permission' ));
$this -> assertEquals ( $perms1 , $perms2 );
}
$this -> assertTrue ( isset ( $caps [ 'moodle/site:approvecourse' ]));
$this -> assertEquals ( $existingcaps [ 'moodle/site:approvecourse' ], $caps [ 'moodle/site:approvecourse' ]);
$this -> assertFalse ( isset ( $caps [ 'mod/page:addinstance' ]));
2013-07-27 10:58:11 +02:00
// Execute plugin.
2012-04-19 08:47:28 +02:00
update_capabilities ( 'mod_page' );
$caps = $DB -> get_records ( 'capabilities' , array (), 'id' , 'name, captype, contextlevel, component, riskbitmask' );
$this -> assertTrue ( isset ( $caps [ 'mod/page:addinstance' ]));
$roles = $DB -> get_records_sql ( 'SELECT DISTINCT roleid AS id FROM {role_capabilities} WHERE capability=? OR capability=?' , array ( 'moodle/course:manageactivities' , 'mod/page:addinstance' ));
foreach ( $roles as $role ) {
$perms1 = array_values ( $DB -> get_records ( 'role_capabilities' , array ( 'capability' => 'moodle/course:manageactivities' , 'roleid' => $role -> id ), 'contextid, permission' , 'contextid, permission' ));
$perms2 = array_values ( $DB -> get_records ( 'role_capabilities' , array ( 'capability' => 'mod/page:addinstance' , 'roleid' => $role -> id ), 'contextid, permission' , 'contextid, permission' ));
}
$this -> assertEquals ( $perms1 , $perms2 );
}
2014-01-14 13:44:17 +00:00
/**
* Tests reset_role_capabilities function .
*/
public function test_reset_role_capabilities () {
global $DB ;
$this -> resetAfterTest ( true );
$generator = $this -> getDataGenerator ();
// Create test course and user, enrol one in the other.
$course = $generator -> create_course ();
$user = $generator -> create_user ();
$roleid = $DB -> get_field ( 'role' , 'id' , array ( 'shortname' => 'student' ), MUST_EXIST );
$generator -> enrol_user ( $user -> id , $course -> id , $roleid );
// Change student role so it DOES have 'mod/forum:addinstance'.
$systemcontext = context_system :: instance ();
assign_capability ( 'mod/forum:addinstance' , CAP_ALLOW , $roleid , $systemcontext -> id );
// Override course so it does NOT allow students 'mod/forum:viewdiscussion'.
$coursecontext = context_course :: instance ( $course -> id );
assign_capability ( 'mod/forum:viewdiscussion' , CAP_PREVENT , $roleid , $coursecontext -> id );
// Check expected capabilities so far.
$this -> assertTrue ( has_capability ( 'mod/forum:addinstance' , $coursecontext , $user ));
$this -> assertFalse ( has_capability ( 'mod/forum:viewdiscussion' , $coursecontext , $user ));
// Oops, allowing student to add forums was a mistake, let's reset the role.
reset_role_capabilities ( $roleid );
// Check new expected capabilities - role capabilities should have been reset,
// while the override at course level should remain.
$this -> assertFalse ( has_capability ( 'mod/forum:addinstance' , $coursecontext , $user ));
$this -> assertFalse ( has_capability ( 'mod/forum:viewdiscussion' , $coursecontext , $user ));
}
2015-03-20 13:46:27 +00:00
/**
* Tests count_role_users function .
*/
public function test_count_role_users () {
global $DB ;
$this -> resetAfterTest ( true );
$generator = self :: getDataGenerator ();
// Create a course in a category, and some users.
$category = $generator -> create_category ();
$course = $generator -> create_course ( array ( 'category' => $category -> id ));
$user1 = $generator -> create_user ();
$user2 = $generator -> create_user ();
$user3 = $generator -> create_user ();
$user4 = $generator -> create_user ();
$user5 = $generator -> create_user ();
$roleid1 = $DB -> get_field ( 'role' , 'id' , array ( 'shortname' => 'manager' ), MUST_EXIST );
$roleid2 = $DB -> get_field ( 'role' , 'id' , array ( 'shortname' => 'coursecreator' ), MUST_EXIST );
// Enrol two users as managers onto the course, and 1 onto the category.
$generator -> enrol_user ( $user1 -> id , $course -> id , $roleid1 );
$generator -> enrol_user ( $user2 -> id , $course -> id , $roleid1 );
$generator -> role_assign ( $roleid1 , $user3 -> id , context_coursecat :: instance ( $category -> id ));
// Enrol 1 user as a coursecreator onto the course, and another onto the category.
// This is to ensure we do not count users with roles that are not specified.
$generator -> enrol_user ( $user4 -> id , $course -> id , $roleid2 );
$generator -> role_assign ( $roleid2 , $user5 -> id , context_coursecat :: instance ( $category -> id ));
// Check that the correct users are found on the course.
$this -> assertEquals ( 2 , count_role_users ( $roleid1 , context_course :: instance ( $course -> id ), false ));
$this -> assertEquals ( 3 , count_role_users ( $roleid1 , context_course :: instance ( $course -> id ), true ));
// Check for the category.
$this -> assertEquals ( 1 , count_role_users ( $roleid1 , context_coursecat :: instance ( $category -> id ), false ));
$this -> assertEquals ( 1 , count_role_users ( $roleid1 , context_coursecat :: instance ( $category -> id ), true ));
// Have a user with the same role at both the category and course level.
$generator -> role_assign ( $roleid1 , $user1 -> id , context_coursecat :: instance ( $category -> id ));
// The course level checks should remain the same.
$this -> assertEquals ( 2 , count_role_users ( $roleid1 , context_course :: instance ( $course -> id ), false ));
$this -> assertEquals ( 3 , count_role_users ( $roleid1 , context_course :: instance ( $course -> id ), true ));
}
2016-08-12 15:13:09 +01:00
2019-02-28 08:28:52 +08:00
/**
* Test fetching users by capability .
*/
public function test_get_users_by_capability () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$student = $this -> getDataGenerator () -> create_user ();
$guest = $DB -> get_record ( 'user' , array ( 'username' => 'guest' ));
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
role_assign ( $studentrole -> id , $student -> id , $coursecontext );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ));
// Note: Here are used default capabilities, the full test is in permission evaluation below,
// use two capabilities that teacher has and one does not, none of them should be allowed for not-logged-in user.
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' )));
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/site:approvecourse' )));
$users = get_users_by_capability ( $coursecontext , 'moodle/backup:backupcourse' );
$this -> assertTrue ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
$this -> assertFalse ( array_key_exists ( $student -> id , $users ));
$this -> assertFalse ( array_key_exists ( $guest -> id , $users ));
$users = get_users_by_capability ( $coursecontext , 'moodle/site:approvecourse' );
$this -> assertFalse ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
$this -> assertFalse ( array_key_exists ( $student -> id , $users ));
$this -> assertFalse ( array_key_exists ( $guest -> id , $users ));
// Test role override.
assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $teacherrole -> id , $coursecontext , true );
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $studentrole -> id , $coursecontext , true );
$users = get_users_by_capability ( $coursecontext , 'moodle/backup:backupcourse' );
$this -> assertFalse ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
$this -> assertTrue ( array_key_exists ( $student -> id , $users ));
$this -> assertFalse ( array_key_exists ( $guest -> id , $users ));
}
2016-08-12 15:13:09 +01:00
/**
* Test updating of role capabilities during upgrade
* @ return void
*/
public function test_get_with_capability_sql () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$teacher = $this -> getDataGenerator () -> create_user ();
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$student = $this -> getDataGenerator () -> create_user ();
$guest = $DB -> get_record ( 'user' , array ( 'username' => 'guest' ));
role_assign ( $teacherrole -> id , $teacher -> id , $coursecontext );
role_assign ( $studentrole -> id , $student -> id , $coursecontext );
$admin = $DB -> get_record ( 'user' , array ( 'username' => 'admin' ));
// Note: Here are used default capabilities, the full test is in permission evaluation below,
// use two capabilities that teacher has and one does not, none of them should be allowed for not-logged-in user.
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/backup:backupcourse' )));
$this -> assertTrue ( $DB -> record_exists ( 'capabilities' , array ( 'name' => 'moodle/site:approvecourse' )));
list ( $sql , $params ) = get_with_capability_sql ( $coursecontext , 'moodle/backup:backupcourse' );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertTrue ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
$this -> assertFalse ( array_key_exists ( $student -> id , $users ));
$this -> assertFalse ( array_key_exists ( $guest -> id , $users ));
list ( $sql , $params ) = get_with_capability_sql ( $coursecontext , 'moodle/site:approvecourse' );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertFalse ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
$this -> assertFalse ( array_key_exists ( $student -> id , $users ));
$this -> assertFalse ( array_key_exists ( $guest -> id , $users ));
// Test role override.
2019-02-28 08:39:20 +08:00
assign_capability ( 'moodle/backup:backupcourse' , CAP_PROHIBIT , $teacherrole -> id , $coursecontext , true );
assign_capability ( 'moodle/backup:backupcourse' , CAP_ALLOW , $studentrole -> id , $coursecontext , true );
2016-08-12 15:13:09 +01:00
2019-02-28 08:39:20 +08:00
list ( $sql , $params ) = get_with_capability_sql ( $coursecontext , 'moodle/backup:backupcourse' );
2016-08-12 15:13:09 +01:00
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertFalse ( array_key_exists ( $teacher -> id , $users ));
$this -> assertFalse ( array_key_exists ( $admin -> id , $users ));
$this -> assertTrue ( array_key_exists ( $student -> id , $users ));
$this -> assertFalse ( array_key_exists ( $guest -> id , $users ));
}
2017-09-11 11:52:23 +08:00
/**
* Test the get_profile_roles () function .
*/
public function test_get_profile_roles () {
global $DB ;
$this -> resetAfterTest ();
$course = $this -> getDataGenerator () -> create_course ();
$coursecontext = context_course :: instance ( $course -> id );
// Assign a student role.
$studentrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'student' ), '*' , MUST_EXIST );
$user1 = $this -> getDataGenerator () -> create_user ();
role_assign ( $studentrole -> id , $user1 -> id , $coursecontext );
// Assign an editing teacher role.
$teacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'editingteacher' ), '*' , MUST_EXIST );
$user2 = $this -> getDataGenerator () -> create_user ();
role_assign ( $teacherrole -> id , $user2 -> id , $coursecontext );
// Create a custom role that can be assigned at course level, but don't assign it yet.
create_role ( 'Custom role' , 'customrole' , 'Custom course role' );
$customrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'customrole' ), '*' , MUST_EXIST );
set_role_contextlevels ( $customrole -> id , [ CONTEXT_COURSE ]);
2017-11-24 12:30:40 +00:00
core_role_set_assign_allowed ( $teacherrole -> id , $customrole -> id ); // Allow teacher to assign the role in the course.
2017-09-11 11:52:23 +08:00
// Set the site policy 'profileroles' to show student, teacher and non-editing teacher roles (i.e. not the custom role).
$neteacherrole = $DB -> get_record ( 'role' , array ( 'shortname' => 'teacher' ), '*' , MUST_EXIST );
set_config ( 'profileroles' , " { $studentrole -> id } , { $teacherrole -> id } , { $neteacherrole -> id } " );
// A student in the course (given they can't assign roles) should see those roles which are:
// - listed in the 'profileroles' site policy AND
// - are assigned in the course context (or parent contexts).
// In this case, the non-editing teacher role is not assigned and should not be returned.
$expected = [
$teacherrole -> id => ( object ) [
'id' => $teacherrole -> id ,
'name' => '' ,
'shortname' => $teacherrole -> shortname ,
'sortorder' => $teacherrole -> sortorder ,
'coursealias' => null
],
$studentrole -> id => ( object ) [
'id' => $studentrole -> id ,
'name' => '' ,
'shortname' => $studentrole -> shortname ,
'sortorder' => $studentrole -> sortorder ,
'coursealias' => null
]
];
$this -> setUser ( $user1 );
$this -> assertEquals ( $expected , get_profile_roles ( $coursecontext ));
// An editing teacher should also see only 2 roles at this stage as only 2 roles are assigned: 'teacher' and 'student'.
$this -> setUser ( $user2 );
$this -> assertEquals ( $expected , get_profile_roles ( $coursecontext ));
// Assign a custom role in the course.
$user3 = $this -> getDataGenerator () -> create_user ();
role_assign ( $customrole -> id , $user3 -> id , $coursecontext );
// Confirm that the teacher can see the custom role now that it's assigned.
$expectedteacher = [
$teacherrole -> id => ( object ) [
'id' => $teacherrole -> id ,
'name' => '' ,
'shortname' => $teacherrole -> shortname ,
'sortorder' => $teacherrole -> sortorder ,
'coursealias' => null
],
$studentrole -> id => ( object ) [
'id' => $studentrole -> id ,
'name' => '' ,
'shortname' => $studentrole -> shortname ,
'sortorder' => $studentrole -> sortorder ,
'coursealias' => null
],
$customrole -> id => ( object ) [
'id' => $customrole -> id ,
'name' => 'Custom role' ,
'shortname' => $customrole -> shortname ,
'sortorder' => $customrole -> sortorder ,
'coursealias' => null
]
];
$this -> setUser ( $user2 );
$this -> assertEquals ( $expectedteacher , get_profile_roles ( $coursecontext ));
// And that the student can't, because the role isn't included in the 'profileroles' site policy.
$expectedstudent = [
$teacherrole -> id => ( object ) [
'id' => $teacherrole -> id ,
'name' => '' ,
'shortname' => $teacherrole -> shortname ,
'sortorder' => $teacherrole -> sortorder ,
'coursealias' => null
],
$studentrole -> id => ( object ) [
'id' => $studentrole -> id ,
'name' => '' ,
'shortname' => $studentrole -> shortname ,
'sortorder' => $studentrole -> sortorder ,
'coursealias' => null
]
];
$this -> setUser ( $user1 );
$this -> assertEquals ( $expectedstudent , get_profile_roles ( $coursecontext ));
2017-09-21 19:49:19 +08:00
// If we have no roles listed in the site policy, the teacher should be able to see the assigned roles.
2017-09-11 11:52:23 +08:00
$expectedteacher = [
$studentrole -> id => ( object ) [
'id' => $studentrole -> id ,
'name' => '' ,
'shortname' => $studentrole -> shortname ,
'sortorder' => $studentrole -> sortorder ,
'coursealias' => null
],
$customrole -> id => ( object ) [
'id' => $customrole -> id ,
'name' => 'Custom role' ,
'shortname' => $customrole -> shortname ,
'sortorder' => $customrole -> sortorder ,
'coursealias' => null
2017-09-21 19:49:19 +08:00
],
$teacherrole -> id => ( object ) [
'id' => $teacherrole -> id ,
'name' => '' ,
'shortname' => $teacherrole -> shortname ,
'sortorder' => $teacherrole -> sortorder ,
'coursealias' => null
],
2017-09-11 11:52:23 +08:00
];
set_config ( 'profileroles' , " " );
$this -> setUser ( $user2 );
$this -> assertEquals ( $expectedteacher , get_profile_roles ( $coursecontext ));
}
2018-10-17 13:36:39 +08:00
/**
* Ensure that the get_parent_contexts () function limits the number of queries it performs .
*/
public function test_get_parent_contexts_preload () {
global $DB ;
$this -> resetAfterTest ();
/*
* Given the following data structure :
* System
* - Category
* --- Category
* ----- Category
* ------- Category
* --------- Course
* ----------- Activity ( Forum )
*/
$contexts = [];
$cat1 = $this -> getDataGenerator () -> create_category ();
$cat2 = $this -> getDataGenerator () -> create_category ([ 'parent' => $cat1 -> id ]);
$cat3 = $this -> getDataGenerator () -> create_category ([ 'parent' => $cat2 -> id ]);
$cat4 = $this -> getDataGenerator () -> create_category ([ 'parent' => $cat3 -> id ]);
$course = $this -> getDataGenerator () -> create_course ([ 'category' => $cat4 -> id ]);
$forum = $this -> getDataGenerator () -> create_module ( 'forum' , [ 'course' => $course -> id ]);
$modcontext = context_module :: instance ( $forum -> cmid );
context_helper :: reset_caches ();
// There should only be a single DB query.
$predbqueries = $DB -> perf_get_reads ();
$parents = $modcontext -> get_parent_contexts ();
// Note: For some databases There is one read, plus one FETCH, plus one CLOSE.
// These all show as reads, when there has actually only been a single query.
$this -> assertLessThanOrEqual ( 3 , $DB -> perf_get_reads () - $predbqueries );
}
2019-02-28 08:28:52 +08:00
/**
* Ensure that get_with_capability_sql and get_with_capability_join respect context locking .
*/
public function test_get_with_capability_sql_locked () {
global $DB ;
$this -> resetAfterTest ();
$generator = $this -> getDataGenerator ();
$cat1 = $generator -> create_category ();
$cat2 = $generator -> create_category ();
$cat1course1 = $generator -> create_course ([ 'category' => $cat1 -> id ]);
$cat1course1forum = $generator -> create_module ( 'forum' , [ 'course' => $cat1course1 ]);
$contexts = ( object ) [
'system' => \context_system :: instance (),
'cat1' => \context_coursecat :: instance ( $cat1 -> id ),
'cat2' => \context_coursecat :: instance ( $cat2 -> id ),
'cat1course1' => \context_course :: instance ( $cat1course1 -> id ),
'cat1course1forum' => \context_module :: instance ( $cat1course1forum -> cmid ),
];
// Test with the 'mod/forum:startdiscussion' capability.
$caput = 'mod/forum:startdiscussion' ;
// Create a test user.
$uut = $generator -> create_and_enrol ( $cat1course1 , 'teacher' );
// Initially the user will be returned by get_users_by_capability.
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayHasKey ( $uut -> id , $users );
// Freezing the forum will remove the user.
set_config ( 'contextlocking' , 1 );
$contexts -> cat1course1forum -> set_locked ( true );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayNotHasKey ( $uut -> id , $users );
// But not if context locking is disabled.
set_config ( 'contextlocking' , 0 );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayHasKey ( $uut -> id , $users );
$contexts -> cat1course1forum -> set_locked ( false );
// Freezing the course will have the same effect.
set_config ( 'contextlocking' , 1 );
$contexts -> cat1course1 -> set_locked ( true );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayNotHasKey ( $uut -> id , $users );
// But not if context locking is disabled.
set_config ( 'contextlocking' , 0 );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayHasKey ( $uut -> id , $users );
$contexts -> cat1course1 -> set_locked ( false );
// Freezing the category will have the same effect.
set_config ( 'contextlocking' , 1 );
$contexts -> cat1 -> set_locked ( true );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayNotHasKey ( $uut -> id , $users );
// But not if context locking is disabled.
set_config ( 'contextlocking' , 0 );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayHasKey ( $uut -> id , $users );
$contexts -> cat1 -> set_locked ( false );
// Freezing an unrelated category will have no effect.
set_config ( 'contextlocking' , 1 );
$contexts -> cat2 -> set_locked ( true );
list ( $sql , $params ) = get_with_capability_sql ( $contexts -> cat1course1forum , $caput );
$users = $DB -> get_records_sql ( $sql , $params );
$this -> assertArrayHasKey ( $uut -> id , $users );
}
/**
* Ensure that get_users_by_capability respects context freezing .
*/
public function test_get_users_by_capability_locked () {
$this -> resetAfterTest ();
$generator = $this -> getDataGenerator ();
$cat1 = $generator -> create_category ();
$cat2 = $generator -> create_category ();
$cat1course1 = $generator -> create_course ([ 'category' => $cat1 -> id ]);
$cat1course1forum = $generator -> create_module ( 'forum' , [ 'course' => $cat1course1 ]);
$contexts = ( object ) [
'system' => \context_system :: instance (),
'cat1' => \context_coursecat :: instance ( $cat1 -> id ),
'cat2' => \context_coursecat :: instance ( $cat2 -> id ),
'cat1course1' => \context_course :: instance ( $cat1course1 -> id ),
'cat1course1forum' => \context_module :: instance ( $cat1course1forum -> cmid ),
];
// Test with the 'mod/forum:startdiscussion' capability.
$caput = 'mod/forum:startdiscussion' ;
// Create a test user.
$uut = $generator -> create_and_enrol ( $cat1course1 , 'teacher' );
// Initially the user will be returned by get_users_by_capability.
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayHasKey ( $uut -> id , $users );
// Freezing the forum will remove the user.
set_config ( 'contextlocking' , 1 );
$contexts -> cat1course1forum -> set_locked ( true );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayNotHasKey ( $uut -> id , $users );
// But not if context locking is disabled.
set_config ( 'contextlocking' , 0 );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayHasKey ( $uut -> id , $users );
$contexts -> cat1course1forum -> set_locked ( false );
// Freezing the course will have the same effect.
set_config ( 'contextlocking' , 1 );
$contexts -> cat1course1 -> set_locked ( true );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayNotHasKey ( $uut -> id , $users );
// But not if context locking is disabled.
set_config ( 'contextlocking' , 0 );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayHasKey ( $uut -> id , $users );
$contexts -> cat1course1 -> set_locked ( false );
// Freezing the category will have the same effect.
set_config ( 'contextlocking' , 1 );
$contexts -> cat1 -> set_locked ( true );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayNotHasKey ( $uut -> id , $users );
// But not if context locking is disabled.
set_config ( 'contextlocking' , 0 );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayHasKey ( $uut -> id , $users );
$contexts -> cat1 -> set_locked ( false );
// Freezing an unrelated category will have no effect.
set_config ( 'contextlocking' , 1 );
$contexts -> cat2 -> set_locked ( true );
$users = get_users_by_capability ( $contexts -> cat1course1forum , $caput );
$this -> assertArrayHasKey ( $uut -> id , $users );
}
2012-03-31 23:51:02 +02:00
}
2013-07-27 10:58:11 +02:00
/**
* Context caching fixture
*/
class context_inspection extends context_helper {
public static function test_context_cache_size () {
return self :: $cache_count ;
}
}