See Release Notes
Long Term Support Release
<?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * External 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 catscaleconfiguration */ < protected $catscaleconfiguration4 = 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);> 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);> 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);> 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);> 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);> 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);> 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);> 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);> 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() { $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() { $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() { $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() { $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() { $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() { $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);> $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() { $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);> $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);> $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() { $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);> $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() { $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);> $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() { $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);> $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() { $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);> $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);> $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() { $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() { $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() { $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() { $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() { $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() { $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);> $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);> $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() { $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);> $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);> $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);> $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);> $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() { $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);> $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);> $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() { $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() { $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() { $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() { $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() { $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);> $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() { $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);> $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() { $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);> $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() { $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);> $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() { $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);> $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() { $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);> $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() { $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() { $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() { $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() { $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() { $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);> $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);> $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);> $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() { $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);> $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);> $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() { $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);> $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);> $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() { $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);> $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() { $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() { $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() { $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() { 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() { $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() { $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() { $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() { $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() { $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() { $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);> $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);> $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() { $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() { 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() { $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() { $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);> $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);> $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);> $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() { $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);> $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);> $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);> $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() { 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);> $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);> $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);> $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() { $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);> $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);> $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() { $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() { $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);> $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);> $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() { 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);> $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);> $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);> $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() { $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);> $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);> $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);> $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() { $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);> $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() { $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() { $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() { $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() { $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() { $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);> $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);> $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() { $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);> $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);> $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() { 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() { 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() { 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() { $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() { $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() { $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); } } }