Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?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 tests.** @package core_competency* @copyright 2016 Frédéric Massart - FMCorz.net* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace core_competency\external;use core_competency\api;use core_competency\course_competency_settings;use core_competency\external;use core_competency\invalid_persistent_exception;use core_competency\plan;use core_competency\plan_competency;use core_competency\related_competency;use core_competency\template;use core_competency\template_competency;use core_competency\user_competency;use core_competency\user_competency_plan;use core_external\external_api;use externallib_advanced_testcase;defined('MOODLE_INTERNAL') || die();global $CFG;require_once($CFG->dirroot . '/webservice/tests/helpers.php');/*** External testcase.** @package core_competency* @copyright 2016 Frédéric Massart - FMCorz.net* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class external_test extends externallib_advanced_testcase {/** @var \stdClass $creator User with enough permissions to create insystem context. */protected $creator = null;/** @var \stdClass $learningplancreator User with enough permissions to create incategory context. */protected $catcreator = null;/** @var \stdClass $category Category */protected $category = null;/** @var \stdClass $user User with enough permissions to view insystem context */protected $user = null;/** @var \stdClass $catuser User with enough permissions to view incategory context */protected $catuser = null;/** @var int Creator role id */protected $creatorrole = null;/** @var int User role id */protected $userrole = null;/** @var \stdClass $scale1 Scale */protected $scale1 = null;/** @var \stdClass $scale2 Scale */protected $scale2 = null;/** @var \stdClass $scale3 Scale */protected $scale3 = null;/** @var \stdClass $scale4 Scale */protected $scale4 = null;/** @var string scaleconfiguration */protected $scaleconfiguration1 = null;/** @var string scaleconfiguration */protected $scaleconfiguration2 = null;/** @var string catscaleconfiguration */protected $scaleconfiguration3 = null;/** @var string category scale configuration. */protected $scaleconfiguration4 = null;/** @var \core_course_category course category record. */protected $othercategory = null;/*** Setup function- we will create a course and add an assign instance to it.*/protected function setUp(): void {global $DB, $CFG;$this->resetAfterTest(true);// Create some users.$creator = $this->getDataGenerator()->create_user();$user = $this->getDataGenerator()->create_user();$catuser = $this->getDataGenerator()->create_user();$category = $this->getDataGenerator()->create_category();$othercategory = $this->getDataGenerator()->create_category();$catcreator = $this->getDataGenerator()->create_user();$syscontext = \context_system::instance();$catcontext = \context_coursecat::instance($category->id);$othercatcontext = \context_coursecat::instance($othercategory->id);// Fetching default authenticated user role.$authrole = $DB->get_record('role', array('id' => $CFG->defaultuserroleid));// Reset all default authenticated users permissions.unassign_capability('moodle/competency:competencygrade', $authrole->id);unassign_capability('moodle/competency:competencymanage', $authrole->id);unassign_capability('moodle/competency:competencyview', $authrole->id);unassign_capability('moodle/competency:planmanage', $authrole->id);unassign_capability('moodle/competency:planmanagedraft', $authrole->id);unassign_capability('moodle/competency:planmanageown', $authrole->id);unassign_capability('moodle/competency:planview', $authrole->id);unassign_capability('moodle/competency:planviewdraft', $authrole->id);unassign_capability('moodle/competency:planviewown', $authrole->id);unassign_capability('moodle/competency:planviewowndraft', $authrole->id);unassign_capability('moodle/competency:templatemanage', $authrole->id);unassign_capability('moodle/competency:templateview', $authrole->id);unassign_capability('moodle/cohort:manage', $authrole->id);unassign_capability('moodle/competency:coursecompetencyconfigure', $authrole->id);// Creating specific roles.$this->creatorrole = create_role('Creator role', 'creatorrole', 'learning plan creator role description');$this->userrole = create_role('User role', 'userrole', 'learning plan user role description');assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id);assign_capability('moodle/competency:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id);assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontext->id);assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id);assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);role_assign($this->creatorrole, $creator->id, $syscontext->id);role_assign($this->creatorrole, $catcreator->id, $catcontext->id);role_assign($this->userrole, $user->id, $syscontext->id);role_assign($this->userrole, $catuser->id, $catcontext->id);$this->creator = $creator;$this->catcreator = $catcreator;$this->user = $user;$this->catuser = $catuser;$this->category = $category;$this->othercategory = $othercategory;$this->scale1 = $this->getDataGenerator()->create_scale(array("scale" => "value1, value2"));$this->scale2 = $this->getDataGenerator()->create_scale(array("scale" => "value3, value4"));$this->scale3 = $this->getDataGenerator()->create_scale(array("scale" => "value5, value6"));$this->scale4 = $this->getDataGenerator()->create_scale(array("scale" => "value7, value8"));$this->scaleconfiguration1 = '[{"scaleid":"'.$this->scale1->id.'"},' .'{"name":"value1","id":1,"scaledefault":1,"proficient":0},' .'{"name":"value2","id":2,"scaledefault":0,"proficient":1}]';$this->scaleconfiguration2 = '[{"scaleid":"'.$this->scale2->id.'"},' .'{"name":"value3","id":1,"scaledefault":1,"proficient":0},' .'{"name":"value4","id":2,"scaledefault":0,"proficient":1}]';$this->scaleconfiguration3 = '[{"scaleid":"'.$this->scale3->id.'"},' .'{"name":"value5","id":1,"scaledefault":1,"proficient":0},' .'{"name":"value6","id":2,"scaledefault":0,"proficient":1}]';$this->scaleconfiguration4 = '[{"scaleid":"'.$this->scale4->id.'"},'.'{"name":"value8","id":1,"scaledefault":1,"proficient":0},' .'{"name":"value8","id":2,"scaledefault":0,"proficient":1}]';accesslib_clear_all_caches_for_unit_testing();}protected function create_competency_framework($number = 1, $system = true) {$scalename = 'scale' . $number;$scalepropname = 'scaleconfiguration' . $number;$framework = array('shortname' => 'shortname' . $number,'idnumber' => 'idnumber' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'scaleid' => $this->$scalename->id,'scaleconfiguration' => $this->$scalepropname,'visible' => true,'contextid' => $system ? \context_system::instance()->id : \context_coursecat::instance($this->category->id)->id);$result = external::create_competency_framework($framework);return (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);}protected function create_plan($number, $userid, $templateid, $status, $duedate) {$plan = array('name' => 'name' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'userid' => $userid,'templateid' => empty($templateid) ? null : $templateid,'status' => $status,'duedate' => $duedate);$result = external::create_plan($plan);return (object) external_api::clean_returnvalue(external::create_plan_returns(), $result);}protected function create_template($number, $system) {$template = array('shortname' => 'shortname' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'duedate' => 0,'visible' => true,'contextid' => $system ? \context_system::instance()->id : \context_coursecat::instance($this->category->id)->id);$result = external::create_template($template);return (object) external_api::clean_returnvalue(external::create_template_returns(), $result);}protected function update_template($templateid, $number) {$template = array('id' => $templateid,'shortname' => 'shortname' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'visible' => true);$result = external::update_template($template);return external_api::clean_returnvalue(external::update_template_returns(), $result);}protected function update_plan($planid, $number, $userid, $templateid, $status, $duedate) {$plan = array('id' => $planid,'name' => 'name' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'userid' => $userid,'templateid' => $templateid,'status' => $status,'duedate' => $duedate);$result = external::update_plan($plan);return external_api::clean_returnvalue(external::update_plan_returns(), $result);}protected function update_competency_framework($id, $number = 1, $system = true) {$scalename = 'scale' . $number;$scalepropname = 'scaleconfiguration' . $number;$framework = array('id' => $id,'shortname' => 'shortname' . $number,'idnumber' => 'idnumber' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'scaleid' => $this->$scalename->id,'scaleconfiguration' => $this->$scalepropname,'visible' => true,'contextid' => $system ? \context_system::instance()->id : \context_coursecat::instance($this->category->id)->id);$result = external::update_competency_framework($framework);return external_api::clean_returnvalue(external::update_competency_framework_returns(), $result);}protected function create_competency($number, $frameworkid) {$competency = array('shortname' => 'shortname' . $number,'idnumber' => 'idnumber' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML,'competencyframeworkid' => $frameworkid);$result = external::create_competency($competency);return (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);}protected function update_competency($id, $number) {$competency = array('id' => $id,'shortname' => 'shortname' . $number,'idnumber' => 'idnumber' . $number,'description' => 'description' . $number,'descriptionformat' => FORMAT_HTML);$result = external::update_competency($competency);return external_api::clean_returnvalue(external::update_competency_returns(), $result);}/*** Test we can't create a competency framework with only read permissions.*/public function test_create_competency_frameworks_with_read_permissions(): void {$this->setUser($this->user);$this->expectException(\required_capability_exception::class);$result = $this->create_competency_framework(1, true);}/*** Test we can't create a competency framework with only read permissions.*/public function test_create_competency_frameworks_with_read_permissions_in_category(): void {$this->setUser($this->catuser);$this->expectException(\required_capability_exception::class);$result = $this->create_competency_framework(1, false);}/*** Test we can create a competency framework with manage permissions.*/public function test_create_competency_frameworks_with_manage_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale1->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);}/*** Test we can create a competency framework with manage permissions.*/public function test_create_competency_frameworks_with_manage_permissions_in_category(): void {$this->setUser($this->catcreator);$result = $this->create_competency_framework(1, false);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->catcreator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale1->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);try {$result = $this->create_competency_framework(1, true);$this->fail('User cannot create a framework at system level.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we cannot create a competency framework with nasty data.*/public function test_create_competency_frameworks_with_nasty_data(): void {$this->setUser($this->creator);$framework = array('shortname' => 'short<a href="">','idnumber' => 'id;"number','description' => 'de<>\\..scription','descriptionformat' => FORMAT_HTML,'scaleid' => $this->scale1->id,'scaleconfiguration' => $this->scaleconfiguration1,'visible' => true,'contextid' => \context_system::instance()->id);$this->expectException(\invalid_parameter_exception::class);$result = external::create_competency_framework($framework);}/*** Test we can read a competency framework with manage permissions.*/public function test_read_competency_frameworks_with_manage_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$id = $result->id;$result = external::read_competency_framework($id);$result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale1->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);}/*** Test we can read a competency framework with manage permissions.*/public function test_read_competency_frameworks_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$insystem = $this->create_competency_framework(1, true);$incat = $this->create_competency_framework(2, false);$this->setUser($this->catcreator);$id = $incat->id;$result = external::read_competency_framework($id);$result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname2', $result->shortname);$this->assertEquals('idnumber2', $result->idnumber);$this->assertEquals('description2', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale2->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration2, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);try {$id = $insystem->id;$result = external::read_competency_framework($id);$result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);$this->fail('User cannot read a framework at system level.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can read a competency framework with read permissions.*/public function test_read_competency_frameworks_with_read_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);// Switch users to someone with less permissions.$this->setUser($this->user);$id = $result->id;$result = external::read_competency_framework($id);$result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale1->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);}/*** Test we can read a competency framework with read permissions.*/public function test_read_competency_frameworks_with_read_permissions_in_category(): void {$this->setUser($this->creator);$insystem = $this->create_competency_framework(1, true);$incat = $this->create_competency_framework(2, false);// Switch users to someone with less permissions.$this->setUser($this->catuser);$id = $incat->id;$result = external::read_competency_framework($id);$result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname2', $result->shortname);$this->assertEquals('idnumber2', $result->idnumber);$this->assertEquals('description2', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale2->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration2, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);// Switching to user with no permissions.try {$result = external::read_competency_framework($insystem->id);$this->fail('Current user cannot should not be able to read the framework.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can delete a competency framework with manage permissions.*/public function test_delete_competency_frameworks_with_manage_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$id = $result->id;$result = external::delete_competency_framework($id);$result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);$this->assertTrue($result);}/*** Test we can delete a competency framework with manage permissions.*/public function test_delete_competency_frameworks_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$insystem = $this->create_competency_framework(1, true);$incat = $this->create_competency_framework(2, false);$this->setUser($this->catcreator);$id = $incat->id;$result = external::delete_competency_framework($id);$result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);$this->assertTrue($result);try {$id = $insystem->id;$result = external::delete_competency_framework($id);$result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);$this->fail('Current user cannot should not be able to delete the framework.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can delete a competency framework with read permissions.*/public function test_delete_competency_frameworks_with_read_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$id = $result->id;// Switch users to someone with less permissions.$this->setUser($this->user);$this->expectException(\required_capability_exception::class);$result = external::delete_competency_framework($id);}/*** Test we can update a competency framework with manage permissions.*/public function test_update_competency_frameworks_with_manage_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$result = $this->update_competency_framework($result->id, 2, true);$this->assertTrue($result);}/*** Test we can update a competency framework with manage permissions.*/public function test_update_competency_frameworks_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$insystem = $this->create_competency_framework(1, true);$incat = $this->create_competency_framework(2, false);$this->setUser($this->catcreator);$id = $incat->id;$result = $this->update_competency_framework($incat->id, 3, false);$this->assertTrue($result);try {$result = $this->update_competency_framework($insystem->id, 4, true);$this->fail('Current user should not be able to update the framework.');} catch (\required_capability_exception $e) {// All good.}}public function test_update_framework_scale(): void {$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$s1 = $this->getDataGenerator()->create_scale();$f1 = $lpg->create_framework(array('scaleid' => $s1->id));$f2 = $lpg->create_framework(array('scaleid' => $s1->id));$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));$this->assertEquals($s1->id, $f1->get('scaleid'));// Make the scale of f2 being used.$lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c2->get('id')));// Changing the framework where the scale is not used.$result = $this->update_competency_framework($f1->get('id'), 3, true);$f1 = new \core_competency\competency_framework($f1->get('id'));$this->assertEquals($this->scale3->id, $f1->get('scaleid'));// Changing the framework where the scale is used.try {$result = $this->update_competency_framework($f2->get('id'), 4, true);$this->fail('The scale cannot be changed once used.');} catch (\core\invalid_persistent_exception $e) {$this->assertMatchesRegularExpression('/scaleid/', $e->getMessage());}}/*** Test we can update a competency framework with read permissions.*/public function test_update_competency_frameworks_with_read_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$this->setUser($this->user);$this->expectException(\required_capability_exception::class);$result = $this->update_competency_framework($result->id, 2, true);}/*** Test we can list and count competency frameworks with manage permissions.*/public function test_list_and_count_competency_frameworks_with_manage_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$result = $this->create_competency_framework(2, true);$result = $this->create_competency_framework(3, true);$result = $this->create_competency_framework(4, false);$result = external::count_competency_frameworks(array('contextid' => \context_system::instance()->id), 'self');$result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);$this->assertEquals($result, 3);$result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,array('contextid' => \context_system::instance()->id), 'self', false);$result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);$this->assertEquals(count($result), 3);$result = (object) $result[0];$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale1->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);}public function test_list_competency_frameworks_with_query(): void {$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework1 = $lpg->create_framework(array('shortname' => 'shortname_beetroot','idnumber' => 'idnumber_cinnamon','description' => 'description','descriptionformat' => FORMAT_HTML,'visible' => true,'contextid' => \context_system::instance()->id));$framework2 = $lpg->create_framework(array('shortname' => 'shortname_citrus','idnumber' => 'idnumber_beer','description' => 'description','descriptionformat' => FORMAT_HTML,'visible' => true,'contextid' => \context_system::instance()->id));// Search on both ID number and shortname.$result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,array('contextid' => \context_system::instance()->id), 'self', false, 'bee');$result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);$this->assertCount(2, $result);$f = (object) array_shift($result);$this->assertEquals($framework1->get('id'), $f->id);$f = (object) array_shift($result);$this->assertEquals($framework2->get('id'), $f->id);// Search on ID number.$result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,array('contextid' => \context_system::instance()->id), 'self', false, 'beer');$result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);$this->assertCount(1, $result);$f = (object) array_shift($result);$this->assertEquals($framework2->get('id'), $f->id);// Search on shortname.$result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,array('contextid' => \context_system::instance()->id), 'self', false, 'cinnamon');$result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);$this->assertCount(1, $result);$f = (object) array_shift($result);$this->assertEquals($framework1->get('id'), $f->id);// No match.$result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,array('contextid' => \context_system::instance()->id), 'self', false, 'pwnd!');$result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);$this->assertCount(0, $result);}/*** Test we can list and count competency frameworks with read permissions.*/public function test_list_and_count_competency_frameworks_with_read_permissions(): void {$this->setUser($this->creator);$result = $this->create_competency_framework(1, true);$result = $this->create_competency_framework(2, true);$result = $this->create_competency_framework(3, true);$result = $this->create_competency_framework(4, false);$this->setUser($this->user);$result = external::count_competency_frameworks(array('contextid' => \context_system::instance()->id), 'self');$result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);$this->assertEquals($result, 3);$result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,array('contextid' => \context_system::instance()->id), 'self', false);$result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);$this->assertEquals(count($result), 3);$result = (object) $result[0];$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals($this->scale1->id, $result->scaleid);$this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);$this->assertEquals(true, $result->visible);}/*** Test we can't create a competency with only read permissions.*/public function test_create_competency_with_read_permissions(): void {$framework = $this->getDataGenerator()->get_plugin_generator('core_competency')->create_framework();$this->setUser($this->user);$this->expectException(\required_capability_exception::class);$competency = $this->create_competency(1, $framework->get('id'));}/*** Test we can create a competency with manage permissions.*/public function test_create_competency_with_manage_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$competency = $this->create_competency(1, $framework->id);$this->assertGreaterThan(0, $competency->timecreated);$this->assertGreaterThan(0, $competency->timemodified);$this->assertEquals($this->creator->id, $competency->usermodified);$this->assertEquals('shortname1', $competency->shortname);$this->assertEquals('idnumber1', $competency->idnumber);$this->assertEquals('description1', $competency->description);$this->assertEquals(FORMAT_HTML, $competency->descriptionformat);$this->assertEquals(0, $competency->parentid);$this->assertEquals($framework->id, $competency->competencyframeworkid);}/*** Test we can create a competency with manage permissions.*/public function test_create_competency_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$insystem = $this->create_competency_framework(1, true);$incat = $this->create_competency_framework(2, false);$this->setUser($this->catcreator);$competency = $this->create_competency(1, $incat->id);$this->assertGreaterThan(0, $competency->timecreated);$this->assertGreaterThan(0, $competency->timemodified);$this->assertEquals($this->catcreator->id, $competency->usermodified);$this->assertEquals('shortname1', $competency->shortname);$this->assertEquals('idnumber1', $competency->idnumber);$this->assertEquals('description1', $competency->description);$this->assertEquals(FORMAT_HTML, $competency->descriptionformat);$this->assertEquals(0, $competency->parentid);$this->assertEquals($incat->id, $competency->competencyframeworkid);try {$competency = $this->create_competency(2, $insystem->id);$this->fail('User should not be able to create a competency in system context.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we cannot create a competency with nasty data.*/public function test_create_competency_with_nasty_data(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$competency = array('shortname' => 'shortname<a href="">','idnumber' => 'id;"number','description' => 'de<>\\..scription','descriptionformat' => FORMAT_HTML,'competencyframeworkid' => $framework->id,'sortorder' => 0);$this->expectException(\invalid_parameter_exception::class);$this->expectExceptionMessage('Invalid external api parameter');$result = external::create_competency($competency);}/*** Test we can read a competency with manage permissions.*/public function test_read_competencies_with_manage_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$competency = $this->create_competency(1, $framework->id);$id = $competency->id;$result = external::read_competency($id);$result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals(0, $result->parentid);$this->assertEquals($framework->id, $result->competencyframeworkid);}/*** Test we can read a competency with manage permissions.*/public function test_read_competencies_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$sysframework = $this->create_competency_framework(1, true);$insystem = $this->create_competency(1, $sysframework->id);$catframework = $this->create_competency_framework(2, false);$incat = $this->create_competency(2, $catframework->id);$this->setUser($this->catcreator);$id = $incat->id;$result = external::read_competency($id);$result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname2', $result->shortname);$this->assertEquals('idnumber2', $result->idnumber);$this->assertEquals('description2', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals(0, $result->parentid);$this->assertEquals($catframework->id, $result->competencyframeworkid);try {external::read_competency($insystem->id);$this->fail('User should not be able to read a competency in system context.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can read a competency with read permissions.*/public function test_read_competencies_with_read_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$competency = $this->create_competency(1, $framework->id);// Switch users to someone with less permissions.$this->setUser($this->user);$id = $competency->id;$result = external::read_competency($id);$result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals(0, $result->parentid);$this->assertEquals($framework->id, $result->competencyframeworkid);}/*** Test we can read a competency with read permissions.*/public function test_read_competencies_with_read_permissions_in_category(): void {$this->setUser($this->creator);$sysframework = $this->create_competency_framework(1, true);$insystem = $this->create_competency(1, $sysframework->id);$catframework = $this->create_competency_framework(2, false);$incat = $this->create_competency(2, $catframework->id);// Switch users to someone with less permissions.$this->setUser($this->catuser);$id = $incat->id;$result = external::read_competency($id);$result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname2', $result->shortname);$this->assertEquals('idnumber2', $result->idnumber);$this->assertEquals('description2', $result->description);$this->assertEquals(FORMAT_HTML, $result->descriptionformat);$this->assertEquals(0, $result->parentid);$this->assertEquals($catframework->id, $result->competencyframeworkid);try {external::read_competency($insystem->id);$this->fail('User should not be able to read a competency in system context.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can delete a competency with manage permissions.*/public function test_delete_competency_with_manage_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$id = $result->id;$result = external::delete_competency($id);$result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);$this->assertTrue($result);}/*** Test we can delete a competency with manage permissions.*/public function test_delete_competency_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$sysframework = $this->create_competency_framework(1, true);$insystem = $this->create_competency(1, $sysframework->id);$catframework = $this->create_competency_framework(2, false);$incat = $this->create_competency(2, $catframework->id);$this->setUser($this->catcreator);$id = $incat->id;$result = external::delete_competency($id);$result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);$this->assertTrue($result);try {$result = external::delete_competency($insystem->id);$this->fail('User should not be able to delete a competency in system context.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can delete a competency with read permissions.*/public function test_delete_competency_with_read_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$id = $result->id;// Switch users to someone with less permissions.$this->setUser($this->user);$this->expectException(\required_capability_exception::class);$result = external::delete_competency($id);}/*** Test we can update a competency with manage permissions.*/public function test_update_competency_with_manage_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$result = $this->update_competency($result->id, 2);$this->assertTrue($result);}/*** Test we can update a competency with manage permissions.*/public function test_update_competency_with_manage_permissions_in_category(): void {$this->setUser($this->creator);$sysframework = $this->create_competency_framework(1, true);$insystem = $this->create_competency(1, $sysframework->id);$catframework = $this->create_competency_framework(2, false);$incat = $this->create_competency(2, $catframework->id);$this->setUser($this->catcreator);$result = $this->update_competency($incat->id, 2);$this->assertTrue($result);try {$result = $this->update_competency($insystem->id, 3);$this->fail('User should not be able to update a competency in system context.');} catch (\required_capability_exception $e) {// All good.}}/*** Test we can update a competency with read permissions.*/public function test_update_competency_with_read_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$this->setUser($this->user);$this->expectException(\required_capability_exception::class);$result = $this->update_competency($result->id, 2);}/*** Test count competencies with filters.*/public function test_count_competencies_with_filters(): void {$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$f1 = $lpg->create_framework();$f2 = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'), 'shortname' => 'A'));$c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$c4 = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));$c5 = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));$result = external::count_competencies(array(array('column' => 'competencyframeworkid', 'value' => $f2->get('id'))));$result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);$this->assertEquals(2, $result);$result = external::count_competencies(array(array('column' => 'competencyframeworkid', 'value' => $f1->get('id'))));$result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);$this->assertEquals(3, $result);$result = external::count_competencies(array(array('column' => 'shortname', 'value' => 'A')));$result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);$this->assertEquals(1, $result);}/*** Test we can list and count competencies with manage permissions.*/public function test_list_and_count_competencies_with_manage_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$result = $this->create_competency(2, $framework->id);$result = $this->create_competency(3, $framework->id);$result = external::count_competencies(array());$result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);$this->assertEquals($result, 3);array('id' => $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10, \context_system::instance()->id));$result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);$this->assertEquals(count($result), 3);$result = (object) $result[0];$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);}/*** Test we can list and count competencies with read permissions.*/public function test_list_and_count_competencies_with_read_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$result = $this->create_competency(2, $framework->id);$result = $this->create_competency(3, $framework->id);$this->setUser($this->user);$result = external::count_competencies(array());$result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);$this->assertEquals($result, 3);array('id' => $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10, \context_system::instance()->id));$result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);$this->assertEquals(count($result), 3);$result = (object) $result[0];$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);}/*** Test we can search for competencies.*/public function test_search_competencies_with_read_permissions(): void {$this->setUser($this->creator);$framework = $this->create_competency_framework(1, true);$result = $this->create_competency(1, $framework->id);$result = $this->create_competency(2, $framework->id);$result = $this->create_competency(3, $framework->id);$this->setUser($this->user);$result = external::search_competencies('short', $framework->id);$result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);$this->assertEquals(count($result), 3);$result = (object) $result[0];$this->assertGreaterThan(0, $result->timecreated);$this->assertGreaterThan(0, $result->timemodified);$this->assertEquals($this->creator->id, $result->usermodified);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals('idnumber1', $result->idnumber);$this->assertEquals('description1', $result->description);}/*** Test plans creation and updates.*/public function test_create_and_update_plans(): void {$syscontext = \context_system::instance();$this->setUser($this->creator);$plan0 = $this->create_plan(1, $this->creator->id, 0, plan::STATUS_ACTIVE, 0);$this->setUser($this->user);try {$plan1 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_DRAFT, 0);$this->fail('Exception expected due to not permissions to create draft plans');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();$this->setUser($this->user);$plan2 = $this->create_plan(3, $this->user->id, 0, plan::STATUS_DRAFT, 0);// Basic update on the plan.$this->assertNotEquals('Updated plan 2 name', $plan2->name);$plan2 = external::update_plan(['id' => $plan2->id, 'name' => 'Updated plan 2 name']);$this->assertEquals('Updated plan 2 name', $plan2->name);try {$plan3 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$this->fail('Exception expected due to not permissions to create active plans');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}try {$plan3 = $this->update_plan($plan2->id, 4, $this->user->id, 0, plan::STATUS_COMPLETE, 0);$this->fail('We cannot complete a plan using api::update_plan().');} catch (\coding_exception $e) {$this->assertTrue(true);}assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();$plan3 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);try {$plan4 = $this->create_plan(6, $this->creator->id, 0, plan::STATUS_COMPLETE, 0);$this->fail('Plans cannot be created as complete.');} catch (\coding_exception $e) {$this->assertMatchesRegularExpression('/A plan cannot be created as complete./', $e->getMessage());}try {$plan0 = $this->update_plan($plan0->id, 1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}unassign_capability('moodle/competency:planmanageown', $this->userrole, $syscontext->id);unassign_capability('moodle/competency:planmanageowndraft', $this->userrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();try {// Cannot be updated even if they created it.$this->update_plan($plan2->id, 1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$this->fail('The user can not update their own plan without permissions.');} catch (\required_capability_exception $e) {$this->assertMatchesRegularExpression('/Manage learning plans./', $e->getMessage());}}/*** Test complete plan.*/public function test_complete_plan(): void {$syscontext = \context_system::instance();$this->setUser($this->creator);$this->setUser($this->user);assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();$this->setUser($this->user);$plan = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$result = external::complete_plan($plan->id);$this->assertTrue($result);}/*** Test reopen plan.*/public function test_reopen_plan(): void {$syscontext = \context_system::instance();$this->setUser($this->creator);$this->setUser($this->user);assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();$this->setUser($this->user);$plan = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);external::complete_plan($plan->id);$result = external::reopen_plan($plan->id);$this->assertTrue($result);}/*** Test that we can read plans.*/public function test_read_plans(): void {global $OUTPUT;$this->setUser($this->creator);$syscontext = \context_system::instance();$plan1 = $this->create_plan(1, $this->user->id, 0, plan::STATUS_DRAFT, 0);$plan2 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$plan3 = $this->create_plan(3, $this->user->id, 0, plan::STATUS_ACTIVE, 0);external::complete_plan($plan3->id);$plan3 = (object) external::read_plan($plan3->id);$data = external::read_plan($plan1->id);$this->assertEquals((array)$plan1, external::read_plan($plan1->id));$data = external::read_plan($plan2->id);$this->assertEquals((array)$plan2, external::read_plan($plan2->id));$data = external::read_plan($plan3->id);$this->assertEquals((array)$plan3, external::read_plan($plan3->id));$this->setUser($this->user);// The normal user can not edit these plans.$plan1->canmanage = false;$plan2->canmanage = false;$plan3->canmanage = false;$plan1->canbeedited = false;$plan2->canbeedited = false;$plan3->canbeedited = false;$plan1->canrequestreview = true;$plan2->canrequestreview = true;$plan3->canrequestreview = true;$plan1->canreview = false;$plan2->canreview = false;$plan3->canreview = false;$plan1->iscompleteallowed = false;$plan2->iscompleteallowed = false;$plan3->iscompleteallowed = false;$plan1->isrequestreviewallowed = true;$plan2->isrequestreviewallowed = true;$plan3->isrequestreviewallowed = true;$plan1->isapproveallowed = false;$plan2->isapproveallowed = false;$plan3->isapproveallowed = false;$plan1->isunapproveallowed = false;$plan2->isunapproveallowed = false;$plan3->isunapproveallowed = false;$plan3->isreopenallowed = false;$plan1->commentarea['canpost'] = false;$plan1->commentarea['canview'] = true;// Prevent the user from seeing their own non-draft plans.assign_capability('moodle/competency:plancommentown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id, true);accesslib_clear_all_caches_for_unit_testing();$this->assertEquals((array)$plan1, external::read_plan($plan1->id));try {external::read_plan($plan2->id);$this->fail('Exception expected due to not permissions to read plan');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}try {external::read_plan($plan3->id);$this->fail('Exception expected due to not permissions to read plan');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}// Allow user to see their plan.assign_capability('moodle/competency:plancommentown', CAP_ALLOW, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planmanageowndraft', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);accesslib_clear_all_caches_for_unit_testing();$plan1->commentarea['canpost'] = true;$plan1->commentarea['canview'] = true;$plan2->commentarea['canpost'] = true;$plan2->isrequestreviewallowed = false;$plan3->commentarea['canpost'] = true;$plan3->isrequestreviewallowed = false;$plan1->commentarea['canpostorhascomments'] = true;$plan2->commentarea['canpostorhascomments'] = true;$plan3->commentarea['canpostorhascomments'] = true;$this->assertEquals((array)$plan1, external::read_plan($plan1->id));$this->assertEquals((array)$plan2, external::read_plan($plan2->id));$this->assertEquals((array)$plan3, external::read_plan($plan3->id));// Allow use to manage their own draft plan.assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planmanageown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id, true);accesslib_clear_all_caches_for_unit_testing();$plan1->canmanage = true;$plan1->canbeedited = true;$plan1->canrequestreview = true;$plan1->isrequestreviewallowed = true;$this->assertEquals((array)$plan1, external::read_plan($plan1->id));try {external::read_plan($plan2->id);$this->fail('Exception expected due to not permissions to read plan');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}try {external::read_plan($plan3->id);$this->fail('Exception expected due to not permissions to read plan');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}// Allow use to manage their plan.assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planmanageowndraft', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id, true);accesslib_clear_all_caches_for_unit_testing();$plan1->canmanage = false;$plan1->canbeedited = false;$plan1->canrequestreview = true;$plan1->canreview = true;$plan1->isrequestreviewallowed = true;$plan1->isapproveallowed = true;$plan1->iscompleteallowed = false;$plan2->canmanage = true;$plan2->canbeedited = true;$plan2->canreview = true;$plan2->iscompleteallowed = true;$plan2->isunapproveallowed = true;$plan3->canmanage = true;$plan3->canreview = true;$plan3->isreopenallowed = true;$this->assertEquals((array)$plan1, external::read_plan($plan1->id));$this->assertEquals((array)$plan2, external::read_plan($plan2->id));$this->assertEquals((array)$plan3, external::read_plan($plan3->id));}public function test_delete_plans(): void {$this->setUser($this->creator);$syscontext = \context_system::instance();$plan1 = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$plan2 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$plan3 = $this->create_plan(3, $this->creator->id, 0, plan::STATUS_ACTIVE, 0);$this->assertTrue(external::delete_plan($plan1->id));unassign_capability('moodle/competency:planmanage', $this->creatorrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();try {external::delete_plan($plan2->id);$this->fail('Exception expected due to not permissions to manage plans');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}$this->setUser($this->user);// Can not delete plans created by other users.try {external::delete_plan($plan2->id);$this->fail('Exception expected due to not permissions to manage plans');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();$this->assertTrue(external::delete_plan($plan2->id));// Can not delete plans created for other users.try {external::delete_plan($plan3->id);$this->fail('Exception expected due to not permissions to manage plans');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}$plan4 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);$this->assertTrue(external::delete_plan($plan4->id));}public function test_delete_plan_removes_relations(): void {$this->setAdminUser();$dg = $this->getDataGenerator();$lpg = $dg->get_plugin_generator('core_competency');$user = $dg->create_user();$plan = $lpg->create_plan(array('userid' => $user->id));$framework = $lpg->create_framework();$comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$pc1 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $comp1->get('id')));$pc2 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $comp2->get('id')));$pc3 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $comp3->get('id')));// Complete the plan to generate user_competency_plan entries.api::complete_plan($plan);// Confirm the data we have.$this->assertEquals(3, plan_competency::count_records(array('planid' => $plan->get('id'))));$this->assertEquals(3, user_competency_plan::count_records(array('planid' => $plan->get('id'), 'userid' => $user->id)));// Delete the plan now.api::delete_plan($plan->get('id'));$this->assertEquals(0, plan_competency::count_records(array('planid' => $plan->get('id'))));$this->assertEquals(0, user_competency_plan::count_records(array('planid' => $plan->get('id'), 'userid' => $user->id)));}public function test_list_plan_competencies(): void {$this->setUser($this->creator);$dg = $this->getDataGenerator();$lpg = $dg->get_plugin_generator('core_competency');$f1 = $lpg->create_framework();$f2 = $lpg->create_framework();$c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$c1c = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$c2a = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));$c2b = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));$tpl = $lpg->create_template();$lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1a->get('id')));$lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1c->get('id')));$lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c2b->get('id')));$plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id')));$uc1a = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1a->get('id'),'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $this->creator->id));$uc1b = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1b->get('id')));$uc2b = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c2b->get('id'),'grade' => 2, 'proficiency' => 1));$ux1a = $lpg->create_user_competency(array('userid' => $this->creator->id, 'competencyid' => $c1a->get('id')));$result = external::list_plan_competencies($plan->get('id'));$result = external::clean_returnvalue(external::list_plan_competencies_returns(), $result);$this->assertCount(3, $result);$this->assertEquals($c1a->get('id'), $result[0]['competency']['id']);$this->assertEquals($this->user->id, $result[0]['usercompetency']['userid']);$this->assertArrayNotHasKey('usercompetencyplan', $result[0]);$this->assertEquals($c1c->get('id'), $result[1]['competency']['id']);$this->assertEquals($this->user->id, $result[1]['usercompetency']['userid']);$this->assertArrayNotHasKey('usercompetencyplan', $result[1]);$this->assertEquals($c2b->get('id'), $result[2]['competency']['id']);$this->assertEquals($this->user->id, $result[2]['usercompetency']['userid']);$this->assertArrayNotHasKey('usercompetencyplan', $result[2]);$this->assertEquals(user_competency::STATUS_IN_REVIEW, $result[0]['usercompetency']['status']);$this->assertEquals(null, $result[1]['usercompetency']['grade']);$this->assertEquals(2, $result[2]['usercompetency']['grade']);$this->assertEquals(1, $result[2]['usercompetency']['proficiency']);// Check the return values when the plan status is complete.$completedplan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'),'status' => plan::STATUS_COMPLETE));$uc1a = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c1a->get('id'),'planid' => $completedplan->get('id')));$uc1b = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c1c->get('id'),'planid' => $completedplan->get('id')));$uc2b = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c2b->get('id'),'planid' => $completedplan->get('id'), 'grade' => 2, 'proficiency' => 1));$ux1a = $lpg->create_user_competency_plan(array('userid' => $this->creator->id, 'competencyid' => $c1a->get('id'),'planid' => $completedplan->get('id')));$result = external::list_plan_competencies($completedplan->get('id'));$result = external::clean_returnvalue(external::list_plan_competencies_returns(), $result);$this->assertCount(3, $result);$this->assertEquals($c1a->get('id'), $result[0]['competency']['id']);$this->assertEquals($this->user->id, $result[0]['usercompetencyplan']['userid']);$this->assertArrayNotHasKey('usercompetency', $result[0]);$this->assertEquals($c1c->get('id'), $result[1]['competency']['id']);$this->assertEquals($this->user->id, $result[1]['usercompetencyplan']['userid']);$this->assertArrayNotHasKey('usercompetency', $result[1]);$this->assertEquals($c2b->get('id'), $result[2]['competency']['id']);$this->assertEquals($this->user->id, $result[2]['usercompetencyplan']['userid']);$this->assertArrayNotHasKey('usercompetency', $result[2]);$this->assertEquals(null, $result[1]['usercompetencyplan']['grade']);$this->assertEquals(2, $result[2]['usercompetencyplan']['grade']);$this->assertEquals(1, $result[2]['usercompetencyplan']['proficiency']);}public function test_add_competency_to_template(): void {$this->setUser($this->creator);$syscontext = \context_system::instance();// Create a template.$template = $this->create_template(1, true);// Create a competency.$framework = $this->create_competency_framework(1, true);$competency = $this->create_competency(1, $framework->id);// Add the competency.external::add_competency_to_template($template->id, $competency->id);// Check that it was added.$this->assertEquals(1, external::count_competencies_in_template($template->id));// Unassign capability.unassign_capability('moodle/competency:templatemanage', $this->creatorrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();// Check we can not add the competency now.try {external::add_competency_to_template($template->id, $competency->id);$this->fail('Exception expected due to not permissions to manage template competencies');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}}public function test_remove_competency_from_template(): void {$syscontext = \context_system::instance();$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');// Create a template.$template = $this->create_template(1, true);// Create a competency.$framework = $lpg->create_framework();$competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));// Add the competency.external::add_competency_to_template($template->id, $competency->get('id'));// Check that it was added.$this->assertEquals(1, external::count_competencies_in_template($template->id));// Check that we can remove the competency.external::remove_competency_from_template($template->id, $competency->get('id'));// Check that it was removed.$this->assertEquals(0, external::count_competencies_in_template($template->id));// Unassign capability.unassign_capability('moodle/competency:templatemanage', $this->creatorrole, $syscontext->id);accesslib_clear_all_caches_for_unit_testing();// Check we can not remove the competency now.try {external::add_competency_to_template($template->id, $competency->get('id'));$this->fail('Exception expected due to not permissions to manage template competencies');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}}/*** Test we can re-order competency frameworks.*/public function test_reorder_template_competencies(): void {$this->setUser($this->creator);$syscontext = \context_system::instance();$onehour = time() + 60 * 60;// Create a template.$template = $this->create_template(1, true);// Create a competency framework.$framework = $this->create_competency_framework(1, true);// Create multiple competencies.$competency1 = $this->create_competency(1, $framework->id);$competency2 = $this->create_competency(2, $framework->id);$competency3 = $this->create_competency(3, $framework->id);$competency4 = $this->create_competency(4, $framework->id);// Add the competencies.external::add_competency_to_template($template->id, $competency1->id);external::add_competency_to_template($template->id, $competency2->id);external::add_competency_to_template($template->id, $competency3->id);external::add_competency_to_template($template->id, $competency4->id);// Test if removing competency from template don't create sortorder holes.external::remove_competency_from_template($template->id, $competency3->id);$templcomp4 = template_competency::get_record(array('templateid' => $template->id,'competencyid' => $competency4->id));$this->assertEquals(2, $templcomp4->get('sortorder'));// This is a move up.external::reorder_template_competency($template->id, $competency4->id, $competency2->id);$result = external::list_competencies_in_template($template->id);$result = external_api::clean_returnvalue(external::list_competencies_in_template_returns(), $result);$r1 = (object) $result[0];$r2 = (object) $result[1];$r3 = (object) $result[2];$this->assertEquals($competency1->id, $r1->id);$this->assertEquals($competency4->id, $r2->id);$this->assertEquals($competency2->id, $r3->id);// This is a move down.external::reorder_template_competency($template->id, $competency1->id, $competency4->id);$result = external::list_competencies_in_template($template->id);$result = external_api::clean_returnvalue(external::list_competencies_in_template_returns(), $result);$r1 = (object) $result[0];$r2 = (object) $result[1];$r3 = (object) $result[2];$this->assertEquals($competency4->id, $r1->id);$this->assertEquals($competency1->id, $r2->id);$this->assertEquals($competency2->id, $r3->id);$this->expectException('\required_capability_exception');$this->setUser($this->user);external::reorder_template_competency($template->id, $competency1->id, $competency2->id);}/*** Test we can duplicate learning plan template.*/public function test_duplicate_learning_plan_template(): void {$this->setUser($this->creator);$syscontext = \context_system::instance();$onehour = time() + 60 * 60;// Create a template.$template = $this->create_template(1, true);// Create a competency framework.$framework = $this->create_competency_framework(1, true);// Create multiple competencies.$competency1 = $this->create_competency(1, $framework->id);$competency2 = $this->create_competency(2, $framework->id);$competency3 = $this->create_competency(3, $framework->id);// Add the competencies.external::add_competency_to_template($template->id, $competency1->id);external::add_competency_to_template($template->id, $competency2->id);external::add_competency_to_template($template->id, $competency3->id);// Duplicate the learning plan template.$duplicatedtemplate = external::duplicate_template($template->id);$result = external::list_competencies_in_template($template->id);$resultduplicated = external::list_competencies_in_template($duplicatedtemplate->id);$this->assertEquals(count($result), count($resultduplicated));$this->assertStringContainsString($template->shortname, $duplicatedtemplate->shortname);$this->assertEquals($duplicatedtemplate->description, $template->description);$this->assertEquals($duplicatedtemplate->descriptionformat, $template->descriptionformat);$this->assertEquals($duplicatedtemplate->visible, $template->visible);}/*** Test that we can return scale values for a scale with the scale ID.*/public function test_get_scale_values(): void {global $DB;$this->setUser($this->creator);// Create a scale.$record = new \stdClass();$record->courseid = 0;$record->userid = $this->creator->id;$record->name = 'Test scale';$record->scale = 'Poor, Not good, Okay, Fine, Excellent';$record->description = '<p>Test scale description.</p>';$record->descriptionformat = 1;$record->timemodified = time();$scaleid = $DB->insert_record('scale', $record);// Expected return value.$expected = array(array('id' => 1,'name' => 'Poor'), array('id' => 2,'name' => 'Not good'), array('id' => 3,'name' => 'Okay'), array('id' => 4,'name' => 'Fine'), array('id' => 5,'name' => 'Excellent'));// Call the webservice.$result = external::get_scale_values($scaleid);$this->assertEquals($expected, $result);}/*** Create a template.*/public function test_create_template(): void {$syscontextid = \context_system::instance()->id;$catcontextid = \context_coursecat::instance($this->category->id)->id;// A user without permission.$this->setUser($this->user);try {$result = $this->create_template(1, true);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// A user without permission in a category.$this->setUser($this->catuser);try {$result = $this->create_template(1, false);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// A user with permissions in the system.$this->setUser($this->creator);$result = $this->create_template(1, true);$this->assertEquals('shortname1', $result->shortname);$this->assertEquals($syscontextid, $result->contextid);$this->assertNotEmpty($result->id);$result = $this->create_template(2, false);$this->assertEquals('shortname2', $result->shortname);$this->assertEquals($catcontextid, $result->contextid);$this->assertNotEmpty($result->id);// A user with permissions in the category.$this->setUser($this->catcreator);try {$result = $this->create_template(3, true);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}$result = $this->create_template(3, false);$this->assertEquals('shortname3', $result->shortname);$this->assertEquals($catcontextid, $result->contextid);$this->assertNotEmpty($result->id);}/*** Read a template.*/public function test_read_template(): void {$syscontextid = \context_system::instance()->id;$catcontextid = \context_coursecat::instance($this->category->id)->id;// Set a due date for the next year.$date = new \DateTime('now');$date->modify('+1 year');$duedate = $date->getTimestamp();// Creating two templates.$this->setUser($this->creator);$systemplate = $this->create_template(1, true);$cattemplate = $this->create_template(2, false);// User without permissions to read in system.assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);accesslib_clear_all_caches_for_unit_testing();$this->setUser($this->user);$this->assertFalse(has_capability('moodle/competency:templateview', \context_system::instance()));try {external::read_template($systemplate->id);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}try {external::read_template($cattemplate->id);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// User with permissions to read in a category.assign_capability('moodle/competency:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);accesslib_clear_all_caches_for_unit_testing();$this->assertFalse(has_capability('moodle/competency:templateview', \context_system::instance()));$this->assertTrue(has_capability('moodle/competency:templateview', \context_coursecat::instance($this->category->id)));try {external::read_template($systemplate->id);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}$result = external::read_template($cattemplate->id);$result = external_api::clean_returnvalue(external::read_template_returns(), $result);$this->assertEquals($cattemplate->id, $result['id']);$this->assertEquals('shortname2', $result['shortname']);$this->assertEquals('description2', $result['description']);$this->assertEquals(FORMAT_HTML, $result['descriptionformat']);$this->assertEquals(1, $result['visible']);$this->assertEquals(0, $result['duedate']);$this->assertEquals(userdate(0), $result['duedateformatted']);// User with permissions to read in the system.assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);accesslib_clear_all_caches_for_unit_testing();$this->assertTrue(has_capability('moodle/competency:templateview', \context_system::instance()));$result = external::read_template($systemplate->id);$result = external_api::clean_returnvalue(external::read_template_returns(), $result);$this->assertEquals($systemplate->id, $result['id']);$this->assertEquals('shortname1', $result['shortname']);$this->assertEquals('description1', $result['description']);$this->assertEquals(FORMAT_HTML, $result['descriptionformat']);$this->assertEquals(true, $result['visible']);$this->assertEquals(0, $result['duedate']);$this->assertEquals(userdate(0), $result['duedateformatted']);$result = external::read_template($cattemplate->id);$result = external_api::clean_returnvalue(external::read_template_returns(), $result);$this->assertEquals($cattemplate->id, $result['id']);$this->assertEquals('shortname2', $result['shortname']);$this->assertEquals('description2', $result['description']);$this->assertEquals(FORMAT_HTML, $result['descriptionformat']);$this->assertEquals(true, $result['visible']);$this->assertEquals(0, $result['duedate']);$this->assertEquals(userdate(0), $result['duedateformatted']);}/*** Update a template.*/public function test_update_template(): void {$syscontextid = \context_system::instance()->id;$catcontextid = \context_coursecat::instance($this->category->id)->id;// Set a due date for the next year.$date = new \DateTime('now');$date->modify('+1 year');$duedate = $date->getTimestamp();// Creating two templates.$this->setUser($this->creator);$systemplate = $this->create_template(1, true);$cattemplate = $this->create_template(2, false);// Trying to update in a without permissions.$this->setUser($this->user);try {$this->update_template($systemplate->id, 3);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}try {$this->update_template($cattemplate->id, 3);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// User with permissions to update in category.$this->setUser($this->catcreator);try {$this->update_template($systemplate->id, 3);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}$result = $this->update_template($cattemplate->id, 3);$this->assertTrue($result);$result = external::read_template($cattemplate->id);$result = external_api::clean_returnvalue(external::read_template_returns(), $result);$this->assertEquals($cattemplate->id, $result['id']);$this->assertEquals('shortname3', $result['shortname']);$this->assertEquals("description3", $result['description']);$this->assertEquals(FORMAT_HTML, $result['descriptionformat']);$this->assertEquals(true, $result['visible']);$this->assertEquals(0, $result['duedate']);$this->assertEquals(userdate(0), $result['duedateformatted']);// User with permissions to update in the system.$this->setUser($this->creator);$result = $this->update_template($systemplate->id, 4);$this->assertTrue($result);$result = external::read_template($systemplate->id);$result = external_api::clean_returnvalue(external::read_template_returns(), $result);$this->assertEquals($systemplate->id, $result['id']);$this->assertEquals('shortname4', $result['shortname']);$this->assertEquals('description4', $result['description']);$this->assertEquals(FORMAT_HTML, $result['descriptionformat']);$this->assertEquals(true, $result['visible']);$this->assertEquals(0, $result['duedate']);$this->assertEquals(userdate(0), $result['duedateformatted']);$result = $this->update_template($cattemplate->id, 5);$this->assertTrue($result);$result = external::read_template($cattemplate->id);$result = external_api::clean_returnvalue(external::read_template_returns(), $result);$this->assertEquals($cattemplate->id, $result['id']);$this->assertEquals('shortname5', $result['shortname']);$this->assertEquals('description5', $result['description']);$this->assertEquals(FORMAT_HTML, $result['descriptionformat']);$this->assertEquals(1, $result['visible']);$this->assertEquals(0, $result['duedate']);$this->assertEquals(userdate(0), $result['duedateformatted']);}/*** Delete a template.*/public function test_delete_template(): void {global $DB;$syscontextid = \context_system::instance()->id;$catcontextid = \context_coursecat::instance($this->category->id)->id;// Creating a few templates.$this->setUser($this->creator);$sys1 = $this->create_template(1, true);$cat1 = $this->create_template(2, false);$cat2 = $this->create_template(3, false);$this->assertTrue($DB->record_exists(template::TABLE, array('id' => $sys1->id)));$this->assertTrue($DB->record_exists(template::TABLE, array('id' => $cat1->id)));$this->assertTrue($DB->record_exists(template::TABLE, array('id' => $cat2->id)));// User without permissions.$this->setUser($this->user);try {external::delete_template($sys1->id);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}try {external::delete_template($cat1->id);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// User with category permissions.$this->setUser($this->catcreator);try {external::delete_template($sys1->id);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}$result = external::delete_template($cat1->id);$result = external_api::clean_returnvalue(external::delete_template_returns(), $result);$this->assertTrue($result);$this->assertFalse($DB->record_exists(template::TABLE, array('id' => $cat1->id)));// User with system permissions.$this->setUser($this->creator);$result = external::delete_template($sys1->id);$result = external_api::clean_returnvalue(external::delete_template_returns(), $result);$this->assertTrue($result);$result = external::delete_template($cat2->id);$result = external_api::clean_returnvalue(external::delete_template_returns(), $result);$this->assertTrue($result);$this->assertFalse($DB->record_exists(template::TABLE, array('id' => $sys1->id)));$this->assertFalse($DB->record_exists(template::TABLE, array('id' => $cat2->id)));}/*** List templates.*/public function test_list_templates(): void {$syscontextid = \context_system::instance()->id;$catcontextid = \context_coursecat::instance($this->category->id)->id;// Creating a few templates.$this->setUser($this->creator);$sys1 = $this->create_template(1, true);$sys2 = $this->create_template(2, true);$cat1 = $this->create_template(3, false);$cat2 = $this->create_template(4, false);// User without permission.$this->setUser($this->user);assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);accesslib_clear_all_caches_for_unit_testing();try {external::list_templates('id', 'ASC', 0, 10, array('contextid' => $syscontextid), 'children', false);$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// User with category permissions.assign_capability('moodle/competency:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);accesslib_clear_all_caches_for_unit_testing();$result = external::list_templates('id', 'ASC', 0, 10, array('contextid' => $syscontextid), 'children', false);$result = external_api::clean_returnvalue(external::list_templates_returns(), $result);$this->assertCount(2, $result);$this->assertEquals($cat1->id, $result[0]['id']);$this->assertEquals($cat2->id, $result[1]['id']);// User with system permissions.assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);accesslib_clear_all_caches_for_unit_testing();$result = external::list_templates('id', 'DESC', 0, 3, array('contextid' => $catcontextid), 'parents', false);$result = external_api::clean_returnvalue(external::list_templates_returns(), $result);$this->assertCount(3, $result);$this->assertEquals($cat2->id, $result[0]['id']);$this->assertEquals($cat1->id, $result[1]['id']);$this->assertEquals($sys2->id, $result[2]['id']);}/*** List templates using competency.*/public function test_list_templates_using_competency(): void {$this->setUser($this->creator);// Create a template.$template1 = $this->create_template(1, true);$template2 = $this->create_template(2, true);$template3 = $this->create_template(3, true);$template4 = $this->create_template(4, true);// Create a competency.$framework = $this->create_competency_framework(1, true);$competency1 = $this->create_competency(1, $framework->id);$competency2 = $this->create_competency(2, $framework->id);// Add the competency.external::add_competency_to_template($template1->id, $competency1->id);external::add_competency_to_template($template2->id, $competency1->id);external::add_competency_to_template($template3->id, $competency1->id);external::add_competency_to_template($template4->id, $competency2->id);$listcomp1 = external::list_templates_using_competency($competency1->id);$listcomp2 = external::list_templates_using_competency($competency2->id);// Test count_templates_using_competency.$counttempcomp1 = external::count_templates_using_competency($competency1->id);$counttempcomp2 = external::count_templates_using_competency($competency2->id);$comptemp1 = $listcomp1[0];$comptemp2 = $listcomp1[1];$comptemp3 = $listcomp1[2];$comptemp4 = $listcomp2[0];$this->assertCount(3, $listcomp1);$this->assertCount(1, $listcomp2);$this->assertEquals(3, $counttempcomp1);$this->assertEquals(1, $counttempcomp2);$this->assertEquals($template1->id, $comptemp1->id);$this->assertEquals($template2->id, $comptemp2->id);$this->assertEquals($template3->id, $comptemp3->id);$this->assertEquals($template4->id, $comptemp4->id);}public function test_count_templates(): void {$syscontextid = \context_system::instance()->id;$catcontextid = \context_coursecat::instance($this->category->id)->id;// Creating a few templates.$this->setUser($this->creator);$sys1 = $this->create_template(1, true);$sys2 = $this->create_template(2, true);$cat1 = $this->create_template(3, false);$cat2 = $this->create_template(4, false);$cat3 = $this->create_template(5, false);// User without permission.$this->setUser($this->user);assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);accesslib_clear_all_caches_for_unit_testing();try {external::count_templates(array('contextid' => $syscontextid), 'children');$this->fail('Invalid permissions');} catch (\required_capability_exception $e) {// All good.}// User with category permissions.assign_capability('moodle/competency:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);accesslib_clear_all_caches_for_unit_testing();$result = external::count_templates(array('contextid' => $syscontextid), 'children');$result = external_api::clean_returnvalue(external::count_templates_returns(), $result);$this->assertEquals(3, $result);// User with system permissions.assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);accesslib_clear_all_caches_for_unit_testing();$result = external::count_templates(array('contextid' => $catcontextid), 'parents');$result = external_api::clean_returnvalue(external::count_templates_returns(), $result);$this->assertEquals(5, $result);}/*** Test that we can add related competencies.** @return void*/public function test_add_related_competency(): void {global $DB;$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$framework2 = $lpg->create_framework();$competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework2->get('id')));// The lower one always as competencyid.$result = external::add_related_competency($competency1->get('id'), $competency2->get('id'));$result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);$this->assertTrue($result);$this->assertTrue($DB->record_exists_select(related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',array('cid' => $competency1->get('id'),'rid' => $competency2->get('id'))));$this->assertFalse($DB->record_exists_select(related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',array('cid' => $competency2->get('id'),'rid' => $competency1->get('id'))));$result = external::add_related_competency($competency3->get('id'), $competency1->get('id'));$result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);$this->assertTrue($result);$this->assertTrue($DB->record_exists_select(related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',array('cid' => $competency1->get('id'),'rid' => $competency3->get('id'))));$this->assertFalse($DB->record_exists_select(related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',array('cid' => $competency3->get('id'),'rid' => $competency1->get('id'))));// We can not allow a duplicate relation, not even in the other direction.$this->assertEquals(1, $DB->count_records_select(related_competency::TABLE,'competencyid = :cid AND relatedcompetencyid = :rid',array('cid' => $competency1->get('id'), 'rid' => $competency2->get('id'))));$this->assertEquals(0, $DB->count_records_select(related_competency::TABLE,'competencyid = :cid AND relatedcompetencyid = :rid',array('rid' => $competency1->get('id'), 'cid' => $competency2->get('id'))));$result = external::add_related_competency($competency2->get('id'), $competency1->get('id'));$result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);$this->assertTrue($result);$this->assertEquals(1, $DB->count_records_select(related_competency::TABLE,'competencyid = :cid AND relatedcompetencyid = :rid',array('cid' => $competency1->get('id'), 'rid' => $competency2->get('id'))));$this->assertEquals(0, $DB->count_records_select(related_competency::TABLE,'competencyid = :cid AND relatedcompetencyid = :rid',array('rid' => $competency1->get('id'), 'cid' => $competency2->get('id'))));// Check that we cannot create links across frameworks.try {external::add_related_competency($competency1->get('id'), $competency4->get('id'));$this->fail('Exception expected due mis-use of shared competencies');} catch (invalid_persistent_exception $e) {// Yay!}// User without permission.$this->setUser($this->user);// Check we can not add the related competency now.try {external::add_related_competency($competency1->get('id'), $competency3->get('id'));$this->fail('Exception expected due to not permissions to manage template competencies');} catch (\moodle_exception $e) {$this->assertEquals('nopermissions', $e->errorcode);}}/*** Test that we can remove related competencies.** @return void*/public function test_remove_related_competency(): void {$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$rc1 = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c2->get('id')));$rc2 = $lpg->create_related_competency(array('competencyid' => $c2->get('id'), 'relatedcompetencyid' => $c3->get('id')));$this->assertEquals(2, related_competency::count_records());// Returns false when the relation does not exist.$result = external::remove_related_competency($c1->get('id'), $c3->get('id'));$result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);$this->assertFalse($result);// Returns true on success.$result = external::remove_related_competency($c2->get('id'), $c3->get('id'));$result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);$this->assertTrue($result);$this->assertEquals(1, related_competency::count_records());// We don't need to specify competencyid and relatedcompetencyid in the right order.$result = external::remove_related_competency($c2->get('id'), $c1->get('id'));$result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);$this->assertTrue($result);$this->assertEquals(0, related_competency::count_records());}/*** Test that we can search and include related competencies.** @return void*/public function test_search_competencies_including_related(): void {$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));// We have 1-2, 1-3, 2-4, and no relation between 2-3 nor 1-4 nor 5.$rc12 = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c2->get('id')));$rc13 = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c3->get('id')));$rc24 = $lpg->create_related_competency(array('competencyid' => $c2->get('id'), 'relatedcompetencyid' => $c4->get('id')));$result = external::search_competencies('comp', $framework->get('id'), true);$result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);$this->assertCount(5, $result);}/*** Test that we can add competency to plan if we have the right capability.** @return void*/public function test_add_competency_to_plan(): void {$this->resetAfterTest(true);$dg = $this->getDataGenerator();$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$usermanage = $dg->create_user();$user = $dg->create_user();$syscontext = \context_system::instance();// Creating specific roles.$managerole = $dg->create_role(array('name' => 'User manage','shortname' => 'manage'));assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id);assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id);$dg->role_assign($managerole, $usermanage->id, $syscontext->id);$this->setUser($usermanage);$plan = array ('userid' => $usermanage->id,'status' => \core_competency\plan::STATUS_ACTIVE);$pl1 = $lpg->create_plan($plan);$framework = $lpg->create_framework();$competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$this->assertTrue(external::add_competency_to_plan($pl1->get('id'), $competency->get('id')));// A competency cannot be added to plan based on template.$template = $lpg->create_template();$plan = array ('userid' => $usermanage->id,'status' => \core_competency\plan::STATUS_ACTIVE,'templateid' => $template->get('id'));$pl2 = $lpg->create_plan($plan);try {external::add_competency_to_plan($pl2->get('id'), $competency->get('id'));$this->fail('A competency cannot be added to plan based on template');} catch (\coding_exception $ex) {$this->assertTrue(true);}// User without capability cannot add competency to a plan.$this->setUser($user);try {external::add_competency_to_plan($pl1->get('id'), $competency->get('id'));$this->fail('User without capability cannot add competency to a plan');} catch (\required_capability_exception $ex) {$this->assertTrue(true);}}/*** Test that we can add competency to plan if we have the right capability.** @return void*/public function test_remove_competency_from_plan(): void {$this->resetAfterTest(true);$dg = $this->getDataGenerator();$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$usermanage = $dg->create_user();$user = $dg->create_user();$syscontext = \context_system::instance();// Creating specific roles.$managerole = $dg->create_role(array('name' => 'User manage','shortname' => 'manage'));assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id);assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id);$dg->role_assign($managerole, $usermanage->id, $syscontext->id);$this->setUser($usermanage);$plan = array ('userid' => $usermanage->id,'status' => \core_competency\plan::STATUS_ACTIVE);$pl1 = $lpg->create_plan($plan);$framework = $lpg->create_framework();$competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$lpg->create_plan_competency(array('planid' => $pl1->get('id'),'competencyid' => $competency->get('id')));$this->assertTrue(external::remove_competency_from_plan($pl1->get('id'), $competency->get('id')));$this->assertCount(0, $pl1->get_competencies());}/*** Test that we can add competency to plan if we have the right capability.** @return void*/public function test_reorder_plan_competency(): void {$this->resetAfterTest(true);$dg = $this->getDataGenerator();$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$usermanage = $dg->create_user();$user = $dg->create_user();$syscontext = \context_system::instance();// Creating specific roles.$managerole = $dg->create_role(array('name' => 'User manage','shortname' => 'manage'));assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id);assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id);$dg->role_assign($managerole, $usermanage->id, $syscontext->id);$this->setUser($usermanage);$plan = array ('userid' => $usermanage->id,'status' => \core_competency\plan::STATUS_ACTIVE);$pl1 = $lpg->create_plan($plan);$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c1->get('id'), 'sortorder' => 1));$lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c2->get('id'), 'sortorder' => 2));$lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c3->get('id'), 'sortorder' => 3));$lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c4->get('id'), 'sortorder' => 4));$lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c5->get('id'), 'sortorder' => 5));// Test if removing competency from plan don't create sortorder holes.external::remove_competency_from_plan($pl1->get('id'), $c4->get('id'));$plancomp5 = plan_competency::get_record(array('planid' => $pl1->get('id'),'competencyid' => $c5->get('id')));$this->assertEquals(3, $plancomp5->get('sortorder'));$this->assertTrue(external::reorder_plan_competency($pl1->get('id'), $c2->get('id'), $c5->get('id')));$this->assertTrue(external::reorder_plan_competency($pl1->get('id'), $c3->get('id'), $c1->get('id')));$plancompetencies = plan_competency::get_records(array('planid' => $pl1->get('id')), 'sortorder', 'ASC');$plcmp1 = $plancompetencies[0];$plcmp2 = $plancompetencies[1];$plcmp3 = $plancompetencies[2];$plcmp4 = $plancompetencies[3];$this->assertEquals($plcmp1->get('competencyid'), $c3->get('id'));$this->assertEquals($plcmp2->get('competencyid'), $c1->get('id'));$this->assertEquals($plcmp3->get('competencyid'), $c5->get('id'));$this->assertEquals($plcmp4->get('competencyid'), $c2->get('id'));}/*** Test resolving sortorder when we creating competency.*/public function test_fix_sortorder_when_creating_competency(): void {$this->resetAfterTest(true);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'sortorder' => 20));$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'sortorder' => 1));$this->assertEquals(0, $c1->get('sortorder'));$this->assertEquals(1, $c2->get('sortorder'));$this->assertEquals(2, $c3->get('sortorder'));}/*** Test resolving sortorder when we delete competency.*/public function test_fix_sortorder_when_delete_competency(): void {$this->resetAfterTest(true);$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2a = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));$c2b = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));$c2c = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));$c2d = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));$this->assertEquals(0, $c1->get('sortorder'));$this->assertEquals(1, $c2->get('sortorder'));$this->assertEquals(0, $c2a->get('sortorder'));$this->assertEquals(1, $c2b->get('sortorder'));$this->assertEquals(2, $c2c->get('sortorder'));$this->assertEquals(3, $c2d->get('sortorder'));$result = external::delete_competency($c1->get('id'));$result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);$c2->read();$c2a->read();$c2b->read();$c2c->read();$c2d->read();$this->assertEquals(0, $c2->get('sortorder'));$this->assertEquals(0, $c2a->get('sortorder'));$this->assertEquals(1, $c2b->get('sortorder'));$this->assertEquals(2, $c2c->get('sortorder'));$this->assertEquals(3, $c2d->get('sortorder'));$result = external::delete_competency($c2b->get('id'));$result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);$c2->read();$c2a->read();$c2c->read();$c2d->read();$this->assertEquals(0, $c2->get('sortorder'));$this->assertEquals(0, $c2a->get('sortorder'));$this->assertEquals(1, $c2c->get('sortorder'));$this->assertEquals(2, $c2d->get('sortorder'));}/*** Test resolving sortorder when moving a competency.*/public function test_fix_sortorder_when_moving_competency(): void {$this->resetAfterTest(true);$this->setUser($this->creator);$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c1a = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));$c1b = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2a = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));$c2b = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));$this->assertEquals(0, $c1->get('sortorder'));$this->assertEquals(0, $c1a->get('sortorder'));$this->assertEquals(1, $c1b->get('sortorder'));$this->assertEquals(1, $c2->get('sortorder'));$this->assertEquals(0, $c2a->get('sortorder'));$this->assertEquals(1, $c2b->get('sortorder'));$result = external::set_parent_competency($c2a->get('id'), $c1->get('id'));$result = external_api::clean_returnvalue(external::set_parent_competency_returns(), $result);$c1->read();$c1a->read();$c1b->read();$c2->read();$c2a->read();$c2b->read();$this->assertEquals(0, $c1->get('sortorder'));$this->assertEquals(0, $c1a->get('sortorder'));$this->assertEquals(1, $c1b->get('sortorder'));$this->assertEquals(2, $c2a->get('sortorder'));$this->assertEquals(1, $c2->get('sortorder'));$this->assertEquals(0, $c2b->get('sortorder'));// Move a root node.$result = external::set_parent_competency($c2->get('id'), $c1b->get('id'));$result = external_api::clean_returnvalue(external::set_parent_competency_returns(), $result);$c1->read();$c1a->read();$c1b->read();$c2->read();$c2a->read();$c2b->read();$this->assertEquals(0, $c1->get('sortorder'));$this->assertEquals(0, $c1a->get('sortorder'));$this->assertEquals(1, $c1b->get('sortorder'));$this->assertEquals(0, $c2->get('sortorder'));$this->assertEquals(0, $c2b->get('sortorder'));$this->assertEquals(2, $c2a->get('sortorder'));}public function test_grade_competency(): void {global $CFG;$this->setUser($this->creator);$dg = $this->getDataGenerator();$lpg = $dg->get_plugin_generator('core_competency');$f1 = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$evidence = external::grade_competency($this->user->id, $c1->get('id'), 1, 'Evil note');$this->assertEquals('The competency rating was manually set.', $evidence->description);$this->assertEquals('A', $evidence->gradename);$this->assertEquals('Evil note', $evidence->note);$this->setUser($this->user);$this->expectException('\required_capability_exception');$evidence = external::grade_competency($this->user->id, $c1->get('id'), 1);}public function test_grade_competency_in_course(): void {global $CFG;$this->setUser($this->creator);$dg = $this->getDataGenerator();$lpg = $dg->get_plugin_generator('core_competency');$course = $dg->create_course(['fullname' => 'Evil course']);$dg->enrol_user($this->creator->id, $course->id, 'editingteacher');$dg->enrol_user($this->user->id, $course->id, 'student');$f1 = $lpg->create_framework();$c1 = $lpg->create_competency(['competencyframeworkid' => $f1->get('id')]);$lpg->create_course_competency(['courseid' => $course->id, 'competencyid' => $c1->get('id')]);$evidence = external::grade_competency_in_course($course->id, $this->user->id, $c1->get('id'), 1, 'Evil note');$this->assertEquals('The competency rating was manually set in the course \'Course: Evil course\'.', $evidence->description);$this->assertEquals('A', $evidence->gradename);$this->assertEquals('Evil note', $evidence->note);$this->setUser($this->user);$this->expectException('\required_capability_exception');$evidence = external::grade_competency_in_course($course->id, $this->user->id, $c1->get('id'), 1);}public function test_grade_competency_in_plan(): void {global $CFG;$this->setUser($this->creator);$dg = $this->getDataGenerator();$lpg = $dg->get_plugin_generator('core_competency');$f1 = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));$tpl = $lpg->create_template();$lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1->get('id')));$plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'), 'name' => 'Evil'));$uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get('id')));$evidence = external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1, 'Evil note');$this->assertEquals('The competency rating was manually set in the learning plan \'Evil\'.', $evidence->description);$this->assertEquals('A', $evidence->gradename);$this->assertEquals('Evil note', $evidence->note);$this->setUser($this->user);$this->expectException('\required_capability_exception');$evidence = external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1);}/*** Test update course competency settings.*/public function test_update_course_competency_settings(): void {$this->resetAfterTest(true);$dg = $this->getDataGenerator();$course = $dg->create_course();$roleid = $dg->create_role();$noobroleid = $dg->create_role();$context = \context_course::instance($course->id);$compmanager = $this->getDataGenerator()->create_user();$compnoob = $this->getDataGenerator()->create_user();assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $roleid, $context->id, true);assign_capability('moodle/competency:coursecompetencyview', CAP_ALLOW, $roleid, $context->id, true);assign_capability('moodle/competency:coursecompetencyview', CAP_ALLOW, $noobroleid, $context->id, true);role_assign($roleid, $compmanager->id, $context->id);role_assign($noobroleid, $compnoob->id, $context->id);$dg->enrol_user($compmanager->id, $course->id, $roleid);$dg->enrol_user($compnoob->id, $course->id, $noobroleid);$this->setUser($compmanager);// Start the test.$result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => true));$settings = course_competency_settings::get_by_courseid($course->id);$this->assertTrue((bool)$settings->get('pushratingstouserplans'));$result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => false));$settings = course_competency_settings::get_by_courseid($course->id);$this->assertFalse((bool)$settings->get('pushratingstouserplans'));$this->setUser($compnoob);$this->expectException('\required_capability_exception');$result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => true));}/*** Test that we can list competencies with a filter.** @return void*/public function test_list_competencies_with_filter(): void {$this->resetAfterTest(true);$this->setAdminUser();$dg = $this->getDataGenerator();$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));// Test if removing competency from plan don't create sortorder holes.$filters = [];$sort = 'id';$order = 'ASC';$skip = 0;$limit = 0;$result = external::list_competencies($filters, $sort, $order, $skip, $limit);$this->assertCount(5, $result);$result = external::list_competencies($filters, $sort, $order, 2, $limit);$this->assertCount(3, $result);$result = external::list_competencies($filters, $sort, $order, 2, 2);$this->assertCount(2, $result);$filter = $result[0]->shortname;$filters[0] = ['column' => 'shortname', 'value' => $filter];$result = external::list_competencies($filters, $sort, $order, $skip, $limit);$this->assertCount(1, $result);$this->assertEquals($filter, $result[0]->shortname);}/*** Test that we can list competencies with a course module.** @return void*/public function test_list_competencies_with_course_module(): void {$this->resetAfterTest(true);$this->setAdminUser();$dg = $this->getDataGenerator();$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');$course = $dg->create_course();$framework = $lpg->create_framework();$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));$cc1 = api::add_competency_to_course($course->id, $c1->get('id'));$cc2 = api::add_competency_to_course($course->id, $c2->get('id'));$cc3 = api::add_competency_to_course($course->id, $c3->get('id'));$pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');$page = $pagegenerator->create_instance(array('course' => $course->id));$cm = get_coursemodule_from_instance('page', $page->id);// Add a link and list again.$ccm1 = api::add_competency_to_course_module($cm, $c1->get('id'));$ccm2 = api::add_competency_to_course_module($cm, $c2->get('id'));// Test list competencies for this course module.$total = external::count_course_module_competencies($cm->id);$result = external::list_course_module_competencies($cm->id);$this->assertCount($total, $result);// Now we should have an array and each element of the array should have a competency and// a coursemodulecompetency.foreach ($result as $instance) {$cmc = $instance['coursemodulecompetency'];$c = $instance['competency'];$this->assertEquals($cmc->competencyid, $c->id);}}}