first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\external;
use core_grades\external\create_gradecategories;
use core_external\external_api;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Unit tests for the core_grades\external\create_gradecategories webservice.
*
* @package core_grades
* @category external
* @copyright 2021 Peter Burnett <peterburnett@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.11
*/
class create_gradecategories_test extends \externallib_advanced_testcase {
/**
* Test create_gradecategories.
*
* @return void
*/
public function test_create_gradecategories(): void {
global $DB;
$this->resetAfterTest(true);
$course = $this->getDataGenerator()->create_course();
$this->setAdminUser();
// Test the most basic gradecategory creation.
$status1 = create_gradecategories::execute($course->id,
[['fullname' => 'Test Category 1', 'options' => []]]);
$status1 = external_api::clean_returnvalue(create_gradecategories::execute_returns(), $status1);
$courseparentcat = \grade_category::fetch_course_category($course->id);
$record1 = $DB->get_record('grade_categories', ['id' => $status1['categoryids'][0]]);
$this->assertEquals('Test Category 1', $record1->fullname);
// Confirm that the parent category for this category is the top level category for the course.
$this->assertEquals($courseparentcat->id, $record1->parent);
$this->assertEquals(2, $record1->depth);
// Now create a category as a child of the newly created category.
$status2 = create_gradecategories::execute($course->id,
[['fullname' => 'Test Category 2', 'options' => ['parentcategoryid' => $record1->id]]]);
$status2 = external_api::clean_returnvalue(create_gradecategories::execute_returns(), $status2);
$record2 = $DB->get_record('grade_categories', ['id' => $status2['categoryids'][0]]);
$this->assertEquals($record1->id, $record2->parent);
$this->assertEquals(3, $record2->depth);
// Check the path is correct.
$this->assertEquals('/' . implode('/', [$courseparentcat->id, $record1->id, $record2->id]) . '/', $record2->path);
// Now create a category with some customised data and check the returns. This customises every value.
$customopts = [
'aggregation' => GRADE_AGGREGATE_MEAN,
'aggregateonlygraded' => 0,
'aggregateoutcomes' => 1,
'droplow' => 1,
'itemname' => 'item',
'iteminfo' => 'info',
'idnumber' => 'idnumber',
'gradetype' => GRADE_TYPE_TEXT,
'grademax' => 5,
'grademin' => 2,
'gradepass' => 3,
'display' => GRADE_DISPLAY_TYPE_LETTER,
// Hack. This must be -2 to use the default setting.
'decimals' => 3,
'hiddenuntil' => time(),
'locktime' => time(),
'weightoverride' => 1,
'aggregationcoef2' => 20,
'parentcategoryid' => $record2->id
];
$status3 = create_gradecategories::execute($course->id,
[['fullname' => 'Test Category 3', 'options' => $customopts]]);
$status3 = external_api::clean_returnvalue(create_gradecategories::execute_returns(), $status3);
$cat3 = new \grade_category(['courseid' => $course->id, 'id' => $status3['categoryids'][0]], true);
$cat3->load_grade_item();
// Lets check all of the data is in the right shape.
$this->assertEquals(GRADE_AGGREGATE_MEAN, $cat3->aggregation);
$this->assertEquals(0, $cat3->aggregateonlygraded);
$this->assertEquals(1, $cat3->aggregateoutcomes);
$this->assertEquals(1, $cat3->droplow);
$this->assertEquals('item', $cat3->grade_item->itemname);
$this->assertEquals('info', $cat3->grade_item->iteminfo);
$this->assertEquals('idnumber', $cat3->grade_item->idnumber);
$this->assertEquals(GRADE_TYPE_TEXT, $cat3->grade_item->gradetype);
$this->assertEquals(5, $cat3->grade_item->grademax);
$this->assertEquals(2, $cat3->grade_item->grademin);
$this->assertEquals(3, $cat3->grade_item->gradepass);
$this->assertEquals(GRADE_DISPLAY_TYPE_LETTER, $cat3->grade_item->display);
$this->assertEquals(3, $cat3->grade_item->decimals);
$this->assertGreaterThanOrEqual($cat3->grade_item->hidden, time());
$this->assertGreaterThanOrEqual($cat3->grade_item->locktime, time());
$this->assertEquals(1, $cat3->grade_item->weightoverride);
// Coefficient is converted to percentage.
$this->assertEquals(0.2, $cat3->grade_item->aggregationcoef2);
$this->assertEquals($record2->id, $cat3->parent);
// Now test creating 2 in parallel, and nesting them.
$status4 = create_gradecategories::execute($course->id, [
[
'fullname' => 'Test Category 4',
'options' => [
'idnumber' => 'secondlevel'
],
],
[
'fullname' => 'Test Category 5',
'options' => [
'idnumber' => 'thirdlevel',
'parentcategoryidnumber' => 'secondlevel'
],
],
]);
$status4 = external_api::clean_returnvalue(create_gradecategories::execute_returns(), $status4);
$secondlevel = $DB->get_record('grade_categories', ['id' => $status4['categoryids'][0]]);
$thirdlevel = $DB->get_record('grade_categories', ['id' => $status4['categoryids'][1]]);
// Confirm that the parent category for secondlevel is the top level category for the course.
$this->assertEquals($courseparentcat->id, $secondlevel->parent);
$this->assertEquals(2, $record1->depth);
// Confirm that the parent category for thirdlevel is the secondlevel category.
$this->assertEquals($secondlevel->id, $thirdlevel->parent);
$this->assertEquals(3, $thirdlevel->depth);
// Check the path is correct.
$this->assertEquals('/' . implode('/', [$courseparentcat->id, $secondlevel->id, $thirdlevel->id]) . '/', $thirdlevel->path);
}
}
+179
View File
@@ -0,0 +1,179 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\external;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Unit tests for the core_grades\external\get_feedback webservice.
*
* @package core_grades
* @category external
* @copyright 2023 Kevin Percy <kevin.percy@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 4.2
*/
class get_feedback_test extends \externallib_advanced_testcase {
/**
* Test get_feedback.
*
* @covers ::get_feedback
* @dataProvider get_feedback_provider
* @param string|null $feedback The feedback text added for the grade item.
* @param array $expected The expected feedback data.
* @return void
*/
public function test_get_feedback(?string $feedback, array $expected): void {
$this->resetAfterTest(true);
$course = $this->getDataGenerator()->create_course();
$user = $this->getDataGenerator()->create_user(['firstname' => 'John', 'lastname' => 'Doe',
'email' => 'johndoe@example.com']);
$this->getDataGenerator()->enrol_user($user->id, $course->id);
$gradeitem = $this->getDataGenerator()->create_grade_item(['itemname' => 'Grade item 1',
'courseid' => $course->id]);
$gradegradedata = [
'itemid' => $gradeitem->id,
'userid' => $user->id,
];
if ($feedback) {
$gradegradedata['feedback'] = $feedback;
}
$this->getDataGenerator()->create_grade_grade($gradegradedata);
$this->setAdminUser();
$feedbackdata = get_feedback::execute($course->id, $user->id, $gradeitem->id);
$this->assertEquals($expected['feedbacktext'], $feedbackdata['feedbacktext']);
$this->assertEquals($expected['title'], $feedbackdata['title']);
$this->assertEquals($expected['fullname'], $feedbackdata['fullname']);
$this->assertEquals($expected['additionalfield'], $feedbackdata['additionalfield']);
}
/**
* Data provider for test_get_feedback().
*
* @return array
*/
public function get_feedback_provider(): array {
return [
'Return when feedback is set.' => [
'Test feedback',
[
'feedbacktext' => 'Test feedback',
'title' => 'Grade item 1',
'fullname' => 'John Doe',
'additionalfield' => 'johndoe@example.com'
]
],
'Return when feedback is not set.' => [
null,
[
'feedbacktext' => null,
'title' => 'Grade item 1',
'fullname' => 'John Doe',
'additionalfield' => 'johndoe@example.com'
]
]
];
}
/**
* Test get_feedback with invalid requests.
*
* @covers ::get_feedback
* @dataProvider get_feedback_invalid_request_provider
* @param string $loggeduserrole The role of the logged user.
* @param bool $feedbacknotincourse Whether to request a feedback for a grade item which is not a part of the course.
* @param array $expectedexception The expected exception.
* @return void
*/
public function test_get_feedback_invalid_request(string $loggeduserrole, bool $feedbacknotincourse,
array $expectedexception = []): void {
$this->resetAfterTest(true);
// Create a course with a user and a grade item.
$course = $this->getDataGenerator()->create_course();
$user = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user->id, $course->id);
$gradeitem = $this->getDataGenerator()->create_grade_item(['courseid' => $course->id]);
// Add feedback for the grade item in course.
$gradegradedata = [
'itemid' => $gradeitem->id,
'userid' => $user->id,
'feedback' => 'Test feedback',
];
$this->getDataGenerator()->create_grade_grade($gradegradedata);
// Set the current user as specified.
if ($loggeduserrole === 'user') {
$this->setUser($user);
} else if ($loggeduserrole === 'guest') {
$this->setGuestUser();
} else {
$this->setAdminUser();
}
if ($feedbacknotincourse) { // Create a new course which will be later used in the feedback request call.
$course = $this->getDataGenerator()->create_course();
}
$this->expectException($expectedexception['exceptionclass']);
if (!empty($expectedexception['exceptionmessage'])) {
$this->expectExceptionMessage($expectedexception['exceptionmessage']);
}
get_feedback::execute($course->id, $user->id, $gradeitem->id);
}
/**
* Data provider for test_get_feedback_invalid_request().
*
* @return array
*/
public function get_feedback_invalid_request_provider(): array {
return [
'Logged user does not have permissions to view feedback.' => [
'user',
false,
['exceptionclass' => \required_capability_exception::class]
],
'Guest user cannot view feedback.' => [
'guest',
false,
['exceptionclass' => \require_login_exception::class]
],
'Request feedback for a grade item which is not a part of the course.' => [
'admin',
true,
[
'exceptionclass' => \invalid_parameter_exception::class,
'exceptionmessage' => 'Course ID and item ID mismatch',
]
]
];
}
}
+197
View File
@@ -0,0 +1,197 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\external;
use core_external\external_api;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Unit tests for the core_grades\external\get_gradable_users.
*
* @package core_grades
* @category external
* @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>
* @covers \core_grades\external\get_gradable_users
*/
class get_gradable_users_test extends \externallib_advanced_testcase {
/**
* Test the behaviour of get_gradable_users.
*
* @dataProvider execute_data
* @param bool $onlyactiveenrol if we should only return active enrolments
* @param bool $grouprestricted if we should only return users within a group
* @param array $expected expected users
*/
public function test_execute(bool $onlyactiveenrol, bool $grouprestricted, array $expected): void {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$generator = $this->getDataGenerator();
$course = $generator->create_course();
// Create and enrol test users.
$student1 = $generator->create_user(['username' => 'student1', 'firstname' => 'Apple', 'lastname' => 'Apricot']);
$student2 = $generator->create_user(['username' => 'student2', 'firstname' => 'Banana', 'lastname' => 'Blueberry']);
$student3 = $generator->create_user(['username' => 'student3', 'firstname' => 'Cherry', 'lastname' => 'Cranberry']);
$student4 = $generator->create_user(['username' => 'student4', 'firstname' => 'Durian', 'lastname' => 'Dracontomelon']);
$student5 = $generator->create_user(['username' => 'student5', 'firstname' => 'Eggplant', 'lastname' => 'Ensete']);
$role = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
$generator->enrol_user($student1->id, $course->id, $role->id);
$generator->enrol_user($student2->id, $course->id, $role->id);
$generator->enrol_user($student3->id, $course->id, $role->id);
$generator->enrol_user($student4->id, $course->id, $role->id);
$generator->enrol_user($student5->id, $course->id, $role->id, 'manual', 0, 0, ENROL_USER_SUSPENDED);
$group1 = $generator->create_group(['courseid' => $course->id]);
$group2 = $generator->create_group(['courseid' => $course->id]);
$generator->create_group_member(['userid' => $student1->id, 'groupid' => $group1->id]);
$generator->create_group_member(['userid' => $student1->id, 'groupid' => $group2->id]);
$generator->create_group_member(['userid' => $student2->id, 'groupid' => $group2->id]);
$generator->create_group_member(['userid' => $student3->id, 'groupid' => $group2->id]);
$DB->set_field('course', 'groupmode', SEPARATEGROUPS, ['id' => $course->id]);
$teacher = $generator->create_user(['username' => 'teacher1']);
$role = $DB->get_record('role', ['shortname' => 'editingteacher'], '*', MUST_EXIST);
$generator->enrol_user($teacher->id, $course->id, $role->id);
$generator->create_module('assign', ['course' => $course->id]);
$groupid = $grouprestricted ? $group2->id : 0;
$result = get_gradable_users::execute($course->id, $groupid, $onlyactiveenrol);
$result = external_api::clean_returnvalue(get_gradable_users::execute_returns(), $result);
$mapped = array_map(function($user) {
return [
'fullname' => $user['fullname'],
'firstname' => $user['firstname'],
'lastname' => $user['lastname'],
'profileimageurl' => $user['profileimageurl'],
];
}, array_values($result['users']));
$this->assertEquals($expected, $mapped);
}
/**
* Data provider for test_execute.
*
* @return array
*/
public function execute_data(): array {
return [
'All users' => [
false,
false,
[
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Apple',
'lastname' => 'Apricot',
'fullname' => 'Apple Apricot',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Banana',
'lastname' => 'Blueberry',
'fullname' => 'Banana Blueberry',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Cherry',
'lastname' => 'Cranberry',
'fullname' => 'Cherry Cranberry',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Durian',
'lastname' => 'Dracontomelon',
'fullname' => 'Durian Dracontomelon',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Eggplant',
'lastname' => 'Ensete',
'fullname' => 'Eggplant Ensete',
],
],
],
'Only active enrolment' => [
true,
false,
[
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Apple',
'lastname' => 'Apricot',
'fullname' => 'Apple Apricot',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Banana',
'lastname' => 'Blueberry',
'fullname' => 'Banana Blueberry',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Cherry',
'lastname' => 'Cranberry',
'fullname' => 'Cherry Cranberry',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Durian',
'lastname' => 'Dracontomelon',
'fullname' => 'Durian Dracontomelon',
],
],
],
'Group restricted' => [
false,
true,
[
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Apple',
'lastname' => 'Apricot',
'fullname' => 'Apple Apricot',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Banana',
'lastname' => 'Blueberry',
'fullname' => 'Banana Blueberry',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Cherry',
'lastname' => 'Cranberry',
'fullname' => 'Cherry Cranberry',
],
],
],
];
}
}
+119
View File
@@ -0,0 +1,119 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\external;
use core_external\external_api;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Unit tests for core_grades\external\get_grade_tree.
*
* @package core_grades
* @category external
* @copyright 2023 Mihail Geshoski <mihail@moodle.com>
* @covers \core_grades\external\get_grade_tree
*/
class get_grade_tree_test extends \externallib_advanced_testcase {
/**
* Test the return value of the external function.
*
* @covers ::execute
* @return void
*/
public function test_execute(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course(['fullname' => 'Course']);
$coursegradecategory = \grade_category::fetch_course_category($course->id);
// Create a grade item 'Grade item' and grade category 'Category 1' within the course grade category.
$gradeitem = $this->getDataGenerator()->create_grade_item(
['courseid' => $course->id, 'itemname' => 'Grade item']);
$gradecategory1 = $this->getDataGenerator()->create_grade_category(
['courseid' => $course->id, 'fullname' => 'Category 1']);
// Create a grade item 'Grade item 1' and grade category 'Category 2' within 'Category 1'.
$gradeitem1 = $this->getDataGenerator()->create_grade_item(
['courseid' => $course->id, 'itemname' => 'Grade item 1', 'categoryid' => $gradecategory1->id]);
$gradecategory2 = $this->getDataGenerator()->create_grade_category(
['courseid' => $course->id, 'fullname' => 'Category 2', 'parent' => $gradecategory1->id]);
// Create a grade item 'Grade item 2' and grade category 'Category 3' (with no children) within 'Category 2'.
$gradeitem2 = $this->getDataGenerator()->create_grade_item(
['courseid' => $course->id, 'itemname' => 'Grade item 2', 'categoryid' => $gradecategory2->id]);
$gradecategory3 = $this->getDataGenerator()->create_grade_category(
['courseid' => $course->id, 'fullname' => 'Category 3', 'parent' => $gradecategory2->id]);
$result = get_grade_tree::execute($course->id);
$result = external_api::clean_returnvalue(get_grade_tree::execute_returns(), $result);
$expected = json_encode([
'id' => $coursegradecategory->id,
'name' => 'Course',
'iscategory' => true,
'haschildcategories' => true,
'children' => [
[
'id' => $gradeitem->id,
'name' => 'Grade item',
'iscategory' => false,
'children' => null
],
[
'id' => $gradecategory1->id,
'name' => 'Category 1',
'iscategory' => true,
'haschildcategories' => true,
'children' => [
[
'id' => $gradeitem1->id,
'name' => 'Grade item 1',
'iscategory' => false,
'children' => null
],
[
'id' => $gradecategory2->id,
'name' => 'Category 2',
'iscategory' => true,
'haschildcategories' => true,
'children' => [
[
'id' => $gradeitem2->id,
'name' => 'Grade item 2',
'iscategory' => false,
'children' => null
],
[
'id' => $gradecategory3->id,
'name' => 'Category 3',
'iscategory' => true,
'haschildcategories' => false,
'children' => null
]
]
]
]
]
]
]);
$this->assertEquals($expected, $result);
}
}
+64
View File
@@ -0,0 +1,64 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\external;
use core_grades\external\get_gradeitems as get_gradeitems;
use core_external\external_api;
use grade_item;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Unit tests for the core_grades\external\get_gradeitems.
*
* @package core_grades
* @category external
* @copyright 2023 Mathew May <Mathew.solutions>
* @covers \core_grades\external\get_gradeitems
*/
class get_gradeitems_test extends \externallib_advanced_testcase {
public function test_execute(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
$this->getDataGenerator()->create_module('h5pactivity', ['course' => $course->id]);
$this->getDataGenerator()->create_module('assign', ['course' => $course->id, 'name' => 'Assignment & grade items']);
$result = get_gradeitems::execute($course->id);
$result = external_api::clean_returnvalue(get_gradeitems::execute_returns(), $result);
$allgradeitems = grade_item::fetch_all(['courseid' => $course->id]);
$gradeitems = array_filter($allgradeitems, function($item) {
$item->itemname = $item->get_name();
$item->category = $item->get_parent_category()->get_name();
return $item->gradetype != GRADE_TYPE_NONE && !$item->is_category_item() && !$item->is_course_item();
});
// Move back from grade items into an array of arrays.
$mapped = array_map(function($item) {
return [
'id' => $item->id,
'itemname' => $item->itemname,
'category' => $item->category
];
}, array_values($gradeitems));
$this->assertEquals($mapped, $result['gradeItems']);
}
}