Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Unit tests for the condition. 19 * 20 * @package availability_grouping 21 * @copyright 2014 The Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 use availability_grouping\condition; 28 29 /** 30 * Unit tests for the condition. 31 * 32 * @package availability_grouping 33 * @copyright 2014 The Open University 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class availability_grouping_condition_testcase extends advanced_testcase { 37 /** 38 * Load required classes. 39 */ 40 public function setUp(): void { 41 // Load the mock info class so that it can be used. 42 global $CFG; 43 require_once($CFG->dirroot . '/availability/tests/fixtures/mock_info.php'); 44 } 45 46 /** 47 * Tests constructing and using condition. 48 */ 49 public function test_usage() { 50 global $CFG, $USER; 51 $this->resetAfterTest(); 52 $CFG->enableavailability = true; 53 54 // Erase static cache before test. 55 condition::wipe_static_cache(); 56 57 // Make a test course and user. 58 $generator = $this->getDataGenerator(); 59 $course = $generator->create_course(); 60 $user = $generator->create_user(); 61 $generator->enrol_user($user->id, $course->id); 62 $info = new \core_availability\mock_info($course, $user->id); 63 64 // Make a test grouping and group. 65 $grouping = $generator->create_grouping(array('courseid' => $course->id, 66 'name' => 'Grouping!')); 67 $group = $generator->create_group(array('courseid' => $course->id)); 68 groups_assign_grouping($grouping->id, $group->id); 69 70 // Do test (not in grouping). 71 $structure = (object)array('type' => 'grouping', 'id' => (int)$grouping->id); 72 $cond = new condition($structure); 73 74 // Check if available (when not available). 75 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 76 $information = $cond->get_description(false, false, $info); 77 $this->assertRegExp('~belong to a group in.*Grouping!~', $information); 78 $this->assertTrue($cond->is_available(true, $info, true, $user->id)); 79 80 // Add user to grouping and refresh cache. 81 groups_add_member($group, $user); 82 get_fast_modinfo($course->id, 0, true); 83 84 // Recheck. 85 $this->assertTrue($cond->is_available(false, $info, true, $user->id)); 86 $this->assertFalse($cond->is_available(true, $info, true, $user->id)); 87 $information = $cond->get_description(false, true, $info); 88 $this->assertRegExp('~do not belong to a group in.*Grouping!~', $information); 89 90 // Admin user doesn't belong to the grouping, but they can access it 91 // either way (positive or NOT) because of accessallgroups. 92 $this->setAdminUser(); 93 $infoadmin = new \core_availability\mock_info($course, $USER->id); 94 $this->assertTrue($cond->is_available(false, $infoadmin, true, $USER->id)); 95 $this->assertTrue($cond->is_available(true, $infoadmin, true, $USER->id)); 96 97 // Grouping that doesn't exist uses 'missing' text. 98 $cond = new condition((object)array('id' => $grouping->id + 1000)); 99 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 100 $information = $cond->get_description(false, false, $info); 101 $this->assertRegExp('~belong to a group in.*(Missing grouping)~', $information); 102 103 // We need an actual cm object to test the 'grouping from cm' option. 104 $pagegen = $generator->get_plugin_generator('mod_page'); 105 $page = $pagegen->create_instance(array('course' => $course->id, 106 'groupingid' => $grouping->id, 'availability' => 107 '{"op":"|","show":true,"c":[{"type":"grouping","activity":true}]}')); 108 rebuild_course_cache($course->id, true); 109 110 // Check if available using the 'from course-module' grouping option. 111 $modinfo = get_fast_modinfo($course, $user->id); 112 $cm = $modinfo->get_cm($page->cmid); 113 $info = new \core_availability\info_module($cm); 114 $information = ''; 115 $this->assertTrue($info->is_available($information, false, $user->id)); 116 117 // Remove user from grouping again and recheck. 118 groups_remove_member($group, $user); 119 get_fast_modinfo($course->id, 0, true); 120 $this->assertFalse($info->is_available($information, false, $user->id)); 121 $this->assertRegExp('~belong to a group in.*Grouping!~', $information); 122 } 123 124 /** 125 * Tests the constructor including error conditions. Also tests the 126 * string conversion feature (intended for debugging only). 127 */ 128 public function test_constructor() { 129 // No parameters. 130 $structure = new stdClass(); 131 try { 132 $cond = new condition($structure); 133 $this->fail(); 134 } catch (coding_exception $e) { 135 $this->assertStringContainsString('Missing ->id / ->activity', $e->getMessage()); 136 } 137 138 // Invalid id (not int). 139 $structure->id = 'bourne'; 140 try { 141 $cond = new condition($structure); 142 $this->fail(); 143 } catch (coding_exception $e) { 144 $this->assertStringContainsString('Invalid ->id', $e->getMessage()); 145 } 146 147 // Invalid activity option (not bool). 148 unset($structure->id); 149 $structure->activity = 42; 150 try { 151 $cond = new condition($structure); 152 $this->fail(); 153 } catch (coding_exception $e) { 154 $this->assertStringContainsString('Invalid ->activity', $e->getMessage()); 155 } 156 157 // Invalid activity option (false). 158 $structure->activity = false; 159 try { 160 $cond = new condition($structure); 161 $this->fail(); 162 } catch (coding_exception $e) { 163 $this->assertStringContainsString('Invalid ->activity', $e->getMessage()); 164 } 165 166 // Valid with id. 167 $structure->id = 123; 168 $cond = new condition($structure); 169 $this->assertEquals('{grouping:#123}', (string)$cond); 170 171 // Valid with activity. 172 unset($structure->id); 173 $structure->activity = true; 174 $cond = new condition($structure); 175 $this->assertEquals('{grouping:CM}', (string)$cond); 176 } 177 178 /** 179 * Tests the save() function. 180 */ 181 public function test_save() { 182 $structure = (object)array('id' => 123); 183 $cond = new condition($structure); 184 $structure->type = 'grouping'; 185 $this->assertEquals($structure, $cond->save()); 186 187 $structure = (object)array('activity' => true); 188 $cond = new condition($structure); 189 $structure->type = 'grouping'; 190 $this->assertEquals($structure, $cond->save()); 191 } 192 193 /** 194 * Tests the update_dependency_id() function. 195 */ 196 public function test_update_dependency_id() { 197 $cond = new condition((object)array('id' => 123)); 198 $this->assertFalse($cond->update_dependency_id('frogs', 123, 456)); 199 $this->assertFalse($cond->update_dependency_id('groupings', 12, 34)); 200 $this->assertTrue($cond->update_dependency_id('groupings', 123, 456)); 201 $after = $cond->save(); 202 $this->assertEquals(456, $after->id); 203 204 $cond = new condition((object)array('activity' => true)); 205 $this->assertFalse($cond->update_dependency_id('frogs', 123, 456)); 206 } 207 208 /** 209 * Tests the filter_users (bulk checking) function. Also tests the SQL 210 * variant get_user_list_sql. 211 */ 212 public function test_filter_users() { 213 global $DB, $CFG; 214 $this->resetAfterTest(); 215 $CFG->enableavailability = true; 216 217 // Erase static cache before test. 218 condition::wipe_static_cache(); 219 220 // Make a test course and some users. 221 $generator = $this->getDataGenerator(); 222 $course = $generator->create_course(); 223 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); 224 $teacher = $generator->create_user(); 225 $generator->enrol_user($teacher->id, $course->id, $roleids['editingteacher']); 226 $allusers = array($teacher->id => $teacher); 227 $students = array(); 228 for ($i = 0; $i < 3; $i++) { 229 $student = $generator->create_user(); 230 $students[$i] = $student; 231 $generator->enrol_user($student->id, $course->id, $roleids['student']); 232 $allusers[$student->id] = $student; 233 } 234 $info = new \core_availability\mock_info($course); 235 $checker = new \core_availability\capability_checker($info->get_context()); 236 237 // Make test groups. 238 $group1 = $generator->create_group(array('courseid' => $course->id)); 239 $group2 = $generator->create_group(array('courseid' => $course->id)); 240 $grouping1 = $generator->create_grouping(array('courseid' => $course->id)); 241 $grouping2 = $generator->create_grouping(array('courseid' => $course->id)); 242 groups_assign_grouping($grouping1->id, $group1->id); 243 groups_assign_grouping($grouping2->id, $group2->id); 244 245 // Make page in grouping 2. 246 $pagegen = $generator->get_plugin_generator('mod_page'); 247 $page = $pagegen->create_instance(array('course' => $course->id, 248 'groupingid' => $grouping2->id, 'availability' => 249 '{"op":"|","show":true,"c":[{"type":"grouping","activity":true}]}')); 250 251 // Assign students to groups as follows (teacher is not in a group): 252 // 0: no groups. 253 // 1: in group 1/grouping 1. 254 // 2: in group 2/grouping 2. 255 groups_add_member($group1, $students[1]); 256 groups_add_member($group2, $students[2]); 257 258 // Test specific grouping. 259 $cond = new condition((object)array('id' => (int)$grouping1->id)); 260 $result = array_keys($cond->filter_user_list($allusers, false, $info, $checker)); 261 ksort($result); 262 $expected = array($teacher->id, $students[1]->id); 263 $this->assertEquals($expected, $result); 264 265 // Test it with get_user_list_sql. 266 list ($sql, $params) = $cond->get_user_list_sql(false, $info, true); 267 $result = $DB->get_fieldset_sql($sql, $params); 268 sort($result); 269 $this->assertEquals($expected, $result); 270 271 // NOT test. 272 $result = array_keys($cond->filter_user_list($allusers, true, $info, $checker)); 273 ksort($result); 274 $expected = array($teacher->id, $students[0]->id, $students[2]->id); 275 $this->assertEquals($expected, $result); 276 277 // NOT with get_user_list_sql. 278 list ($sql, $params) = $cond->get_user_list_sql(true, $info, true); 279 $result = $DB->get_fieldset_sql($sql, $params); 280 sort($result); 281 $this->assertEquals($expected, $result); 282 283 // Test course-module grouping. 284 $modinfo = get_fast_modinfo($course); 285 $cm = $modinfo->get_cm($page->cmid); 286 $info = new \core_availability\info_module($cm); 287 $result = array_keys($info->filter_user_list($allusers, $course)); 288 $expected = array($teacher->id, $students[2]->id); 289 $this->assertEquals($expected, $result); 290 291 // With get_user_list_sql. 292 list ($sql, $params) = $info->get_user_list_sql(true); 293 $result = $DB->get_fieldset_sql($sql, $params); 294 sort($result); 295 $this->assertEquals($expected, $result); 296 } 297 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body