See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
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 * External function test for get_user_attempts. 19 * 20 * @package mod_h5pactivity 21 * @category external 22 * @since Moodle 3.11 23 * @copyright 2020 Ilya Tregubov <ilya@moodle.com> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 namespace mod_h5pactivity\external; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 33 34 use mod_h5pactivity\local\manager; 35 use external_api; 36 use externallib_advanced_testcase; 37 38 /** 39 * External function test for get_user_attempts. 40 * 41 * @package mod_h5pactivity 42 * @copyright 2020 Ilya Tregubov <ilya@moodle.com> 43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 44 */ 45 class get_user_attempts_test extends externallib_advanced_testcase { 46 47 /** 48 * Test the behaviour of get_user_attempts getting more than one user at once. 49 * 50 * @dataProvider execute_multipleusers_data 51 * @param string $loginuser the user which calls the webservice 52 * @param string[] $participants the users to get the data 53 * @param string[] $warnings the expected users with warnings 54 * @param string[] $resultusers expected users in the resultusers 55 */ 56 public function test_execute_multipleusers(string $loginuser, array $participants, 57 array $warnings, array $resultusers): void { 58 $this->resetAfterTest(); 59 $this->setAdminUser(); 60 61 $course = $this->getDataGenerator()->create_course(); 62 $activity = $this->getDataGenerator()->create_module('h5pactivity', 63 ['course' => $course]); 64 65 $manager = manager::create_from_instance($activity); 66 $cm = $manager->get_coursemodule(); 67 68 $users = ['editingteacher' => $this->getDataGenerator()->create_and_enrol($course, 'editingteacher')]; 69 70 // Prepare users. 71 foreach ($participants as $participant) { 72 if ($participant == 'noenrolled') { 73 $users[$participant] = $this->getDataGenerator()->create_user(); 74 } else { 75 $users[$participant] = $this->getDataGenerator()->create_and_enrol($course, 'student'); 76 } 77 } 78 79 // Generate attempts (student1 with 1 attempt, student2 with 2 etc). 80 $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity'); 81 82 $attemptcount = 1; 83 foreach ($users as $key => $user) { 84 if (($key == 'noattempts') || ($key == 'noenrolled') || ($key == 'editingteacher')) { 85 $countattempts[$user->id] = 0; 86 } else { 87 $params = ['cmid' => $cm->id, 'userid' => $user->id]; 88 for ($i = 1; $i <= $attemptcount; $i++) { 89 $generator->create_content($activity, $params); 90 } 91 $countattempts[$user->id] = $attemptcount; 92 $attemptcount++; 93 } 94 } 95 96 // Execute external method. 97 $this->setUser($users[$loginuser]); 98 99 if ($loginuser == 'student1') { 100 $this->expectException('moodle_exception'); 101 $this->expectExceptionMessage('h5pactivity:reviewattempts required view attempts' . 102 ' of all enrolled users'); 103 } 104 $result = get_user_attempts::execute($activity->id); 105 $result = external_api::clean_returnvalue( 106 get_user_attempts::execute_returns(), 107 $result 108 ); 109 110 $this->assertCount(count($warnings), $result['warnings']); 111 // Teacher is excluded. 112 $this->assertCount(count($resultusers), $result['usersattempts']); 113 114 $expectedwarnings = []; 115 foreach ($warnings as $warninguser) { 116 $id = $users[$warninguser]->id; 117 $expectedwarnings[$id] = $warninguser; 118 } 119 120 foreach ($result['warnings'] as $warning) { 121 $this->assertEquals('user', $warning['item']); 122 $this->assertEquals(1, $warning['warningcode']); 123 $this->assertArrayHasKey($warning['itemid'], $expectedwarnings); 124 } 125 126 $expectedusers = []; 127 foreach ($resultusers as $resultuser) { 128 $id = $users[$resultuser]->id; 129 $expectedusers[$id] = $resultuser; 130 } 131 132 foreach ($result['usersattempts'] as $usersattempts) { 133 $this->assertArrayHasKey('userid', $usersattempts); 134 $userid = $usersattempts['userid']; 135 $this->assertArrayHasKey($userid, $expectedusers); 136 $this->assertCount($countattempts[$userid], $usersattempts['attempts']); 137 if ($countattempts[$userid]) { 138 $this->assertArrayHasKey('scored', $usersattempts); 139 } 140 } 141 } 142 143 /** 144 * Data provider for the test_execute_multipleusers. 145 * 146 * @return array 147 */ 148 public function execute_multipleusers_data(): array { 149 return [ 150 // Teacher checks. 151 'Teacher checking students with attempts' => [ 152 'editingteacher', 153 ['student1', 'student2', 'student3', 'student4', 'student5'], 154 [], 155 ['student1', 'student2', 'student3', 'student4', 'student5'], 156 ], 157 'Teacher checking 2 students with atempts and one not' => [ 158 'editingteacher', 159 ['student1', 'student2', 'noattempts'], 160 [], 161 ['student1', 'student2', 'noattempts'], 162 ], 163 'Teacher checking no students' => [ 164 'editingteacher', 165 [], 166 [], 167 [], 168 ], 169 'Teacher checking one student and a no enrolled user' => [ 170 'editingteacher', 171 ['student1', 'noenrolled'], 172 [], 173 ['student1'], 174 ], 175 176 // Permission check. 177 'Student checking attempts and another user' => [ 178 'student1', 179 ['student1', 'student2'], 180 ['student2'], 181 ['student1'], 182 ], 183 ]; 184 } 185 186 /** 187 * Data provider for {@see test_execute_with_sortorder} 188 * 189 * @return array[] 190 */ 191 public function execute_with_sortorder(): array { 192 return [ 193 'Sort by id' => ['id', ['user01', 'user02']], 194 'Sort by id desc' => ['id desc', ['user02', 'user01']], 195 'Sort by id asc' => ['id asc', ['user01', 'user02']], 196 'Sort by firstname' => ['firstname', ['user01', 'user02']], 197 'Sort by firstname desc' => ['firstname desc', ['user02', 'user01']], 198 'Sort by firstname asc' => ['firstname asc', ['user01', 'user02']], 199 'Sort by lastname' => ['lastname', ['user02', 'user01']], 200 'Sort by lastname desc' => ['lastname desc', ['user01', 'user02']], 201 'Sort by lastname asc' => ['lastname asc', ['user02', 'user01']], 202 // Edge cases (should fall back to default). 203 'Sort by empty string' => ['', ['user01', 'user02']], 204 'Sort by invalid field' => ['invalid', ['user01', 'user02']], 205 ]; 206 } 207 208 /** 209 * Test external execute method with sortorder 210 * 211 * @param string $sortorder 212 * @param string[] $expectedorder 213 * 214 * @dataProvider execute_with_sortorder 215 */ 216 public function test_execute_with_sortorder(string $sortorder, array $expectedorder): void { 217 $this->resetAfterTest(); 218 $this->setAdminUser(); 219 220 // Create course, module. 221 $course = $this->getDataGenerator()->create_course(); 222 $module = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 223 224 // Couple of enrolled users in the course. 225 $users['user01'] = $this->getDataGenerator()->create_and_enrol($course, 'student', [ 226 'username' => 'user01', 227 'firstname' => 'Adam', 228 'lastname' => 'Zebra', 229 ]); 230 $users['user02'] = $this->getDataGenerator()->create_and_enrol($course, 'student', [ 231 'username' => 'user02', 232 'firstname' => 'Zoe', 233 'lastname' => 'Apples', 234 ]); 235 236 $result = external_api::clean_returnvalue( 237 get_user_attempts::execute_returns(), 238 get_user_attempts::execute($module->id, $sortorder) 239 ); 240 241 // Map expected order of usernames to user IDs. 242 $expectedorderbyuserid = array_map(static function(string $username) use ($users): int { 243 return $users[$username]->id; 244 }, $expectedorder); 245 246 // The order should match the ordering of user attempt user IDs. 247 $this->assertEquals($expectedorderbyuserid, array_column($result['usersattempts'], 'userid')); 248 } 249 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body