See Release Notes
Long Term Support Release
<?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/>. /** * External function test for get_user_attempts. * * @package mod_h5pactivity * @category external * @since Moodle 3.11 * @copyright 2020 Ilya Tregubov <ilya@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_h5pactivity\external; defined('MOODLE_INTERNAL') || die(); global $CFG; require_once($CFG->dirroot . '/webservice/tests/helpers.php'); use mod_h5pactivity\local\manager;< use external_api;> use core_external\external_api;use externallib_advanced_testcase; /** * External function test for get_user_attempts. * * @package mod_h5pactivity * @copyright 2020 Ilya Tregubov <ilya@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class get_user_attempts_test extends externallib_advanced_testcase { /** * Test the behaviour of get_user_attempts getting more than one user at once. * * @dataProvider execute_multipleusers_data * @param string $loginuser the user which calls the webservice * @param string[] $participants the users to get the data * @param string[] $warnings the expected users with warnings * @param string[] $resultusers expected users in the resultusers */ public function test_execute_multipleusers(string $loginuser, array $participants, array $warnings, array $resultusers): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); $manager = manager::create_from_instance($activity); $cm = $manager->get_coursemodule(); $users = ['editingteacher' => $this->getDataGenerator()->create_and_enrol($course, 'editingteacher')]; // Prepare users. foreach ($participants as $participant) { if ($participant == 'noenrolled') { $users[$participant] = $this->getDataGenerator()->create_user(); } else { $users[$participant] = $this->getDataGenerator()->create_and_enrol($course, 'student'); } } // Generate attempts (student1 with 1 attempt, student2 with 2 etc). $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity'); $attemptcount = 1; foreach ($users as $key => $user) { if (($key == 'noattempts') || ($key == 'noenrolled') || ($key == 'editingteacher')) { $countattempts[$user->id] = 0; } else { $params = ['cmid' => $cm->id, 'userid' => $user->id]; for ($i = 1; $i <= $attemptcount; $i++) { $generator->create_content($activity, $params); } $countattempts[$user->id] = $attemptcount; $attemptcount++; } } // Execute external method. $this->setUser($users[$loginuser]); if ($loginuser == 'student1') { $this->expectException('moodle_exception'); $this->expectExceptionMessage('h5pactivity:reviewattempts required view attempts' . ' of all enrolled users'); } $result = get_user_attempts::execute($activity->id); $result = external_api::clean_returnvalue( get_user_attempts::execute_returns(), $result ); $this->assertCount(count($warnings), $result['warnings']); // Teacher is excluded. $this->assertCount(count($resultusers), $result['usersattempts']); $expectedwarnings = []; foreach ($warnings as $warninguser) { $id = $users[$warninguser]->id; $expectedwarnings[$id] = $warninguser; } foreach ($result['warnings'] as $warning) { $this->assertEquals('user', $warning['item']); $this->assertEquals(1, $warning['warningcode']); $this->assertArrayHasKey($warning['itemid'], $expectedwarnings); } $expectedusers = []; foreach ($resultusers as $resultuser) { $id = $users[$resultuser]->id; $expectedusers[$id] = $resultuser; } foreach ($result['usersattempts'] as $usersattempts) { $this->assertArrayHasKey('userid', $usersattempts); $userid = $usersattempts['userid']; $this->assertArrayHasKey($userid, $expectedusers); $this->assertCount($countattempts[$userid], $usersattempts['attempts']); if ($countattempts[$userid]) { $this->assertArrayHasKey('scored', $usersattempts); } } } /** * Data provider for the test_execute_multipleusers. * * @return array */ public function execute_multipleusers_data(): array { return [ // Teacher checks. 'Teacher checking students with attempts' => [ 'editingteacher', ['student1', 'student2', 'student3', 'student4', 'student5'], [], ['student1', 'student2', 'student3', 'student4', 'student5'], ], 'Teacher checking 2 students with atempts and one not' => [ 'editingteacher', ['student1', 'student2', 'noattempts'], [], ['student1', 'student2', 'noattempts'], ], 'Teacher checking no students' => [ 'editingteacher', [], [], [], ], 'Teacher checking one student and a no enrolled user' => [ 'editingteacher', ['student1', 'noenrolled'], [], ['student1'], ], // Permission check. 'Student checking attempts and another user' => [ 'student1', ['student1', 'student2'], ['student2'], ['student1'], ], ]; } /** * Data provider for {@see test_execute_with_sortorder} * * @return array[] */ public function execute_with_sortorder(): array { return [ 'Sort by id' => ['id', ['user01', 'user02']], 'Sort by id desc' => ['id desc', ['user02', 'user01']], 'Sort by id asc' => ['id asc', ['user01', 'user02']], 'Sort by firstname' => ['firstname', ['user01', 'user02']], 'Sort by firstname desc' => ['firstname desc', ['user02', 'user01']], 'Sort by firstname asc' => ['firstname asc', ['user01', 'user02']], 'Sort by lastname' => ['lastname', ['user02', 'user01']], 'Sort by lastname desc' => ['lastname desc', ['user01', 'user02']], 'Sort by lastname asc' => ['lastname asc', ['user02', 'user01']], // Edge cases (should fall back to default). 'Sort by empty string' => ['', ['user01', 'user02']], 'Sort by invalid field' => ['invalid', ['user01', 'user02']], ]; } /** * Test external execute method with sortorder * * @param string $sortorder * @param string[] $expectedorder * * @dataProvider execute_with_sortorder */ public function test_execute_with_sortorder(string $sortorder, array $expectedorder): void { $this->resetAfterTest(); $this->setAdminUser(); // Create course, module. $course = $this->getDataGenerator()->create_course(); $module = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); // Couple of enrolled users in the course. $users['user01'] = $this->getDataGenerator()->create_and_enrol($course, 'student', [ 'username' => 'user01', 'firstname' => 'Adam', 'lastname' => 'Zebra', ]); $users['user02'] = $this->getDataGenerator()->create_and_enrol($course, 'student', [ 'username' => 'user02', 'firstname' => 'Zoe', 'lastname' => 'Apples', ]); $result = external_api::clean_returnvalue( get_user_attempts::execute_returns(), get_user_attempts::execute($module->id, $sortorder) ); // Map expected order of usernames to user IDs. $expectedorderbyuserid = array_map(static function(string $username) use ($users): int { return $users[$username]->id; }, $expectedorder); // The order should match the ordering of user attempt user IDs. $this->assertEquals($expectedorderbyuserid, array_column($result['usersattempts'], 'userid')); } }