first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,319 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Competency ruleoutcome override grade tests
*
* @package core_competency
* @copyright 2022 Matthew Hilton <matthewhilton@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class competency_override_test extends \advanced_testcase {
/** @var \stdClass course record. */
protected $course;
/** @var \stdClass user record. */
protected $user;
/** @var \stdClass block instance record. */
protected $scale;
/** @var competency_framework loading competency frameworks from the DB. */
protected $framework;
/** @var plan loading competency plans from the DB. */
protected $plan;
/** @var competency loading competency from the DB. */
protected $comp1;
/** @var competency loading competency from the DB. */
protected $comp2;
/** @var \stdClass course module. */
protected $cm;
/** @var \completion_info completion information. */
protected $completion;
/** @var \context_course context course. */
protected $context;
public function setUp(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
// Create user in course.
$c1 = $dg->create_course((object) ['enablecompletion' => true]);
$u1 = $dg->create_user();
$dg->enrol_user($u1->id, $c1->id);
// Create framework with three values.
$scale = $dg->create_scale(["scale" => "not,partially,fully"]);
$scaleconfiguration = json_encode([
['scaleid' => $scale->id],
['id' => 1, 'scaledefault' => 1, 'proficient' => 1]
]);
$framework = $lpg->create_framework([
'scaleid' => $scale->id,
'scaleconfiguration' => $scaleconfiguration
]);
$plan = $lpg->create_plan(['userid' => $u1->id]);
$comp1 = $lpg->create_competency([
'competencyframeworkid' => $framework->get('id'),
'scaleid' => $scale->id,
'scaleconfiguration' => $scaleconfiguration
]);
$comp2 = $lpg->create_competency([
'competencyframeworkid' => $framework->get('id'),
'scaleid' => $scale->id,
'scaleconfiguration' => $scaleconfiguration
]);
api::add_competency_to_plan($plan->get('id'), $comp1->get('id'));
api::add_competency_to_plan($plan->get('id'), $comp2->get('id'));
$lpg->create_course_competency([
'courseid' => $c1->id,
'competencyid' => $comp1->get('id'),
'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE,
]);
$lpg->create_course_competency([
'courseid' => $c1->id,
'competencyid' => $comp2->get('id'),
'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE,
]);
$label = $dg->create_module('label', ['course' => $c1, 'completion' => COMPLETION_VIEWED, 'completionview' => 1]);
$cm = get_coursemodule_from_instance('label', $label->id);
$completion = new \completion_info($c1);
$this->assertEquals(COMPLETION_ENABLED, $completion->is_enabled($cm));
// Link course module with the competency and setup a rule to complete the competency when the module is completed.
api::add_competency_to_course_module($cm, $comp1->get('id'));
api::add_competency_to_course_module($cm, $comp2->get('id'));
$coursemodulecomps = api::list_course_module_competencies_in_course_module($cm);
$this->assertCount(2, $coursemodulecomps);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE);
$this->course = $c1;
$this->user = $u1;
$this->scale = $scale;
$this->framework = $framework;
$this->plan = $plan;
$this->comp1 = $comp1;
$this->comp2 = $comp2;
$this->cm = $cm;
$this->completion = new \completion_info($c1);
$this->context = \context_course::instance($this->course->id);
}
/**
* Test ruleoutcome overridegrade is correctly applied when coursemodule completion is processed.
*
* @covers \core_competency\api::set_course_module_competency_ruleoutcome
*/
public function test_ruleoutcome_overridegrade(): void {
// Initially the competency (and hence all the child competencies) should not be complete for the user.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(0, $plancomp->usercompetency->get('grade'));
$this->assertEquals(0, $usercomp->get('grade'));
$this->assertEquals(0, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(0, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(0, $usercomp2->get('grade'));
$this->assertEquals(0, $coursecomp2->get('grade'));
// Update the course module completion state to complete and trigger a competency update.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// Comptency should now be complete for user, plan, and course now that the course module is completed.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(1, $plancomp->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp->get('grade'));
$this->assertEquals(1, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(1, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp2->get('grade'));
$this->assertEquals(1, $coursecomp2->get('grade'));
// Change the competency completion for the user by adding evidence.
api::add_evidence($this->user->id, $this->comp1, $this->context,
evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 2);
api::add_evidence($this->user->id, $this->comp2, $this->context,
evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 2);
// After adding evidence, the competencies should now reflect the new grade value.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(2, $plancomp->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// Update the course module competency to incomplete. This will not change the competency status.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_INCOMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(2, $plancomp->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// Re-complete the course module, so that it attempts to re-complete the competencies.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// By default, this will not override the existing grade, so it should remain the same as before.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(2, $plancomp->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// Update the completion rule for only competency 1 to $overridegrade = true.
$coursemodulecomps = api::list_course_module_competencies_in_course_module($this->cm);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE,
true);
// Mark as incomplete then re-complete the course module.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_INCOMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// Because the rule is now set to override existing grades, the grade should have now updated as per the ruleoutcome.
// However the second competency didn't have this rule set, so it will not be overriden.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(1, $plancomp->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp->get('grade'));
$this->assertEquals(1, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// If competency 2 is changed now to override and re-completed, it will update the same as competency 1.
api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE,
true);
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_INCOMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// Now both the competencies have $overridegrade = true,
// they should both reflect the ruleoutcome after the completion above was processed.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(1, $plancomp->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp->get('grade'));
$this->assertEquals(1, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(1, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp2->get('grade'));
$this->assertEquals(1, $coursecomp2->get('grade'));
}
/**
* Test competency backup and restore correctly restores the ruleoutcome overridegrade value.
*
* @covers \core_competency\api::set_course_module_competency_ruleoutcome
*/
public function test_override_backup_restore(): void {
global $CFG;
require_once($CFG->dirroot . '/course/externallib.php');
// Set one to override grade and another to not override grade.
$coursemodulecomps = api::list_course_module_competencies_in_course_module($this->cm);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE,
false);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE,
true);
// Duplicate the course (backup and restore).
$duplicated = \core_course_external::duplicate_course($this->course->id, 'test', 'test', $this->course->category);
// Get the new course modules.
$newcoursemodules = get_coursemodules_in_course('label', $duplicated['id']);
$this->assertCount(1, $newcoursemodules);
$cm = array_pop($newcoursemodules);
// Get the comeptencies for this cm.
$newcoursemodulecomps = api::list_course_module_competencies_in_course_module($cm);
$this->assertCount(2, $newcoursemodulecomps);
// Ensure the override grade settings are restored properly.
$this->assertEquals($coursemodulecomps[0]->get('overridegrade'), $newcoursemodulecomps[0]->get('overridegrade'));
$this->assertEquals($coursemodulecomps[1]->get('overridegrade'), $newcoursemodulecomps[1]->get('overridegrade'));
}
/**
* Gets the course, user and plan competency for the given competency ID
*
* @param int $compid ID of the competency.
* @return array array containing the three related competencies
*/
private function get_related_competencies(int $compid): array {
$coursecomp = api::get_user_competency_in_course($this->course->id, $this->user->id, $compid);
$usercomp = api::get_user_competency($this->user->id, $compid);
$plancomp = api::get_plan_competency($this->plan, $compid);
return [$coursecomp, $plancomp, $usercomp];
}
}
+366
View File
@@ -0,0 +1,366 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Competency rule testcase.
*
* @package core_competency
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class competency_rule_test extends \externallib_advanced_testcase {
public function test_rule_all_matching(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$u1 = $this->getDataGenerator()->create_user();
// Set up the framework and competencies.
$framework = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
$c11 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
$c111 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c11->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
$c112 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c11->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
$c12 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
$c13 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
$c131 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c13->get('id'),
'ruletype' => 'core_competency\competency_rule_all'));
// Create some user competency records.
$uc1 = $lpg->create_user_competency(array('competencyid' => $c1->get('id'), 'userid' => $u1->id));
$uc11 = $lpg->create_user_competency(array('competencyid' => $c11->get('id'), 'userid' => $u1->id,
'grade' => 1, 'proficiency' => 1));
$uc111 = $lpg->create_user_competency(array('competencyid' => $c111->get('id'), 'userid' => $u1->id,
'grade' => 1, 'proficiency' => 1));
$uc112 = $lpg->create_user_competency(array('competencyid' => $c112->get('id'), 'userid' => $u1->id,
'grade' => 1, 'proficiency' => 1));
$uc12 = $lpg->create_user_competency(array('competencyid' => $c12->get('id'), 'userid' => $u1->id));
$uc13 = new user_competency(0, (object) array('userid' => $u1->id, 'competencyid' => $c13->get('id')));
// Not all children are met.
$cr = new competency_rule_all($c1);
$this->assertFalse($cr->matches($uc1));
// All children are met.
$cr = new competency_rule_all($c11);
$this->assertTrue($cr->matches($uc11));
// The competency doesn't have any children.
$cr = new competency_rule_all($c12);
$this->assertFalse($cr->matches($uc12));
// The competency doesn't have saved user competency records.
$cr = new competency_rule_all($c13);
$this->assertFalse($cr->matches($uc13));
}
public function test_rule_points_validation(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$framework = $lpg->create_framework();
$framework2 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
$c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$cx = $lpg->create_competency(array('competencyframeworkid' => $framework2->get('id')));
$c1->set('ruletype', 'core_competency\competency_rule_points');
$rule = new competency_rule_points($c1);
// Invalid config.
$config = json_encode(array());
$this->assertFalse($rule->validate_config($config));
// Missing required points.
$config = json_encode(array(
'base' => array(),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Invalid required points.
$config = json_encode(array(
'base' => array('points' => 'abc'),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Less than 1 required points.
$config = json_encode(array(
'base' => array('points' => 0),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Not enough required points.
$config = json_encode(array(
'base' => array('points' => 3),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Duplicate competency.
$config = json_encode(array(
'base' => array('points' => 1),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Competency includes itself.
$config = json_encode(array(
'base' => array('points' => 1),
'competencies' => array(
array('id' => $c1->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Cannot use negative points.
$config = json_encode(array(
'base' => array('points' => 1),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => -1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// Not competencies set.
$config = json_encode(array(
'base' => array('points' => 1),
'competencies' => array(
)
));
$this->assertFalse($rule->validate_config($config));
// There is a competency that is not a child.
$config = json_encode(array(
'base' => array('points' => 1),
'competencies' => array(
array('id' => $c1->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c2->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// There is a competency from another framework in there.
$config = json_encode(array(
'base' => array('points' => 1),
'competencies' => array(
array('id' => $cx->get('id'), 'points' => 1, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 1, 'required' => 0),
)
));
$this->assertFalse($rule->validate_config($config));
// A normal config.
$config = json_encode(array(
'base' => array('points' => 4),
'competencies' => array(
array('id' => $c2->get('id'), 'points' => 3, 'required' => 0),
array('id' => $c3->get('id'), 'points' => 2, 'required' => 1),
)
));
$this->assertTrue($rule->validate_config($config));
}
public function test_rule_points_matching(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$u1 = $this->getDataGenerator()->create_user();
// Set up the framework and competencies.
$framework = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$c1->set('ruletype', 'core_competency\competency_rule_points');
$comprule = new competency_rule_points($c1);
$c11 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
$c12 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
$c13 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
$c14 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
// Create some user competency records.
$uc1 = $lpg->create_user_competency(array('competencyid' => $c1->get('id'), 'userid' => $u1->id));
$uc11 = $lpg->create_user_competency(array('competencyid' => $c11->get('id'), 'userid' => $u1->id,
'grade' => 1, 'proficiency' => 1));
$uc12 = $lpg->create_user_competency(array('competencyid' => $c12->get('id'), 'userid' => $u1->id,
'grade' => 1, 'proficiency' => 1));
$uc13 = $lpg->create_user_competency(array('competencyid' => $c13->get('id'), 'userid' => $u1->id));
// Enough points.
$rule = array(
'base' => array('points' => 8),
'competencies' => array(
array(
'id' => $c11->get('id'),
'points' => 4,
'required' => 0
),
array(
'id' => $c12->get('id'),
'points' => 4,
'required' => 0
),
)
);
$c1->set('ruleconfig', json_encode($rule));
$c1->update();
$this->assertTrue($comprule->matches($uc1));
// Not enough points.
$rule = array(
'base' => array('points' => 8),
'competencies' => array(
array(
'id' => $c11->get('id'),
'points' => 4,
'required' => 0
),
array(
'id' => $c13->get('id'),
'points' => 4,
'required' => 0
),
)
);
$c1->set('ruleconfig', json_encode($rule));
$c1->update();
$this->assertFalse($comprule->matches($uc1));
// One required that is not met but points were OK.
$rule = array(
'base' => array('points' => 8),
'competencies' => array(
array(
'id' => $c11->get('id'),
'points' => 4,
'required' => 0
),
array(
'id' => $c12->get('id'),
'points' => 4,
'required' => 0
),
array(
'id' => $c13->get('id'),
'points' => 4,
'required' => 1
),
)
);
$c1->set('ruleconfig', json_encode($rule));
$c1->update();
$this->assertFalse($comprule->matches($uc1));
// One required, one not, should match.
$rule = array(
'base' => array('points' => 8),
'competencies' => array(
array(
'id' => $c11->get('id'),
'points' => 4,
'required' => 0
),
array(
'id' => $c12->get('id'),
'points' => 4,
'required' => 1
),
)
);
$c1->set('ruleconfig', json_encode($rule));
$c1->update();
$this->assertTrue($comprule->matches($uc1));
// All required and should match.
$rule = array(
'base' => array('points' => 8),
'competencies' => array(
array(
'id' => $c11->get('id'),
'points' => 4,
'required' => 1
),
array(
'id' => $c12->get('id'),
'points' => 4,
'required' => 1
),
)
);
$c1->set('ruleconfig', json_encode($rule));
$c1->update();
$this->assertTrue($comprule->matches($uc1));
// All required, but one doesn't have a user record.
$rule = array(
'base' => array('points' => 4),
'competencies' => array(
array(
'id' => $c12->get('id'),
'points' => 4,
'required' => 1
),
array(
'id' => $c14->get('id'),
'points' => 4,
'required' => 1
),
)
);
$c1->set('ruleconfig', json_encode($rule));
$c1->update();
$this->assertFalse($comprule->matches($uc1));
}
}
+60
View File
@@ -0,0 +1,60 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Competency 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 competency_test extends \advanced_testcase {
public function test_get_framework_depth(): void {
$this->resetAfterTest();
$ccg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$f1 = $ccg->create_framework();
$f2 = $ccg->create_framework();
$f3 = $ccg->create_framework();
$f4 = $ccg->create_framework();
$f1c1 = $ccg->create_competency(['competencyframeworkid' => $f1->get('id')]);
$f1c11 = $ccg->create_competency(['competencyframeworkid' => $f1->get('id'), 'parentid' => $f1c1->get('id')]);
$f1c111 = $ccg->create_competency(['competencyframeworkid' => $f1->get('id'), 'parentid' => $f1c11->get('id')]);
$f1c1111 = $ccg->create_competency(['competencyframeworkid' => $f1->get('id'), 'parentid' => $f1c111->get('id')]);
$f2c1 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id')]);
$f2c2 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id')]);
$f2c21 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id'), 'parentid' => $f2c2->get('id')]);
$f2c22 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id'), 'parentid' => $f2c2->get('id')]);
$f2c211 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id'), 'parentid' => $f2c21->get('id')]);
$f2c221 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id'), 'parentid' => $f2c22->get('id')]);
$f2c222 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id'), 'parentid' => $f2c22->get('id')]);
$f2c223 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id'), 'parentid' => $f2c22->get('id')]);
$f2c3 = $ccg->create_competency(['competencyframeworkid' => $f2->get('id')]);
$f3c1 = $ccg->create_competency(['competencyframeworkid' => $f3->get('id')]);
$this->assertEquals(4, competency::get_framework_depth($f1->get('id')));
$this->assertEquals(3, competency::get_framework_depth($f2->get('id')));
$this->assertEquals(1, competency::get_framework_depth($f3->get('id')));
$this->assertEquals(0, competency::get_framework_depth($f4->get('id')));
}
}
@@ -0,0 +1,114 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* This test ensures that the course competency settings are applied and work correctly.
*
* @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 course_competency_settings_test extends \advanced_testcase {
public function test_who_can_change_settings(): void {
global $CFG, $DB;
$this->resetAfterTest(true);
$syscontext = \context_system::instance();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$role = create_role('Settings changer role', 'settingschanger', 'Someone who can change course competency settings');
assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $role, $syscontext->id);
assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $role, $syscontext->id);
assign_capability('moodle/competency:coursecompetencyview', CAP_ALLOW, $role, $syscontext->id);
assign_capability('moodle/competency:planview', CAP_ALLOW, $role, $syscontext->id);
$gradedrole = create_role('Graded role', 'graded', 'Someone who can be graded');
assign_capability('moodle/competency:coursecompetencygradable', CAP_ALLOW, $gradedrole, $syscontext->id);
$c1 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$framework = $lpg->create_framework();
$comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$lpg->create_course_competency(array('competencyid' => $comp1->get('id'), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp2->get('id'), 'courseid' => $c1->id));
// Enrol the user.
$dg->enrol_user($u1->id, $c1->id);
role_assign($gradedrole, $u1->id, $syscontext->id);
// Assign roles.
role_assign($role, $u2->id, $syscontext->id);
$this->setUser($u2);
set_config('pushcourseratingstouserplans', true, 'core_competency');
$coursesettings = course_competency_settings::get_by_courseid($c1->id);
$this->assertTrue((boolean)$coursesettings->get('pushratingstouserplans'));
set_config('pushcourseratingstouserplans', false, 'core_competency');
$coursesettings = course_competency_settings::get_by_courseid($c1->id);
$this->assertFalse((boolean)$coursesettings->get('pushratingstouserplans'));
api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => true));
$coursesettings = course_competency_settings::get_by_courseid($c1->id);
$this->assertTrue((boolean)$coursesettings->get('pushratingstouserplans'));
set_config('pushcourseratingstouserplans', true, 'core_competency');
api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => false));
$coursesettings = course_competency_settings::get_by_courseid($c1->id);
$this->assertFalse((boolean)$coursesettings->get('pushratingstouserplans'));
// Right now the setting is false.
api::grade_competency_in_course($c1->id, $u1->id, $comp1->get('id'), 1, 'Note');
$filterparams = array(
'userid' => $u1->id,
'competencyid' => $comp1->get('id'),
);
$usercompcourse = \core_competency\user_competency_course::get_record($filterparams);
$usercomp = \core_competency\user_competency::get_record($filterparams);
// No grade in plan - only a grade in the course.
$this->assertEmpty($usercomp->get('grade'));
$this->assertEquals(1, $usercompcourse->get('grade'));
api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => true));
api::grade_competency_in_course($c1->id, $u1->id, $comp1->get('id'), 2, 'Note 2');
$filterparams = array(
'userid' => $u1->id,
'competencyid' => $comp1->get('id'),
);
$usercompcourse = \core_competency\user_competency_course::get_record($filterparams);
$usercomp = \core_competency\user_competency::get_record($filterparams);
// Updated grade in plan - updated grade in the course.
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $usercompcourse->get('grade'));
$this->setUser($u3);
$this->expectException('required_capability_exception');
api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => false));
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Course competency persistent 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 course_competency_test extends \advanced_testcase {
public function test_get_courses_with_competency_and_user(): void {
global $CFG, $DB;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$c3 = $dg->create_course();
$c4 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$flatfileplugin = enrol_get_plugin('flatfile');
$flatfileinstanceid = $flatfileplugin->add_instance($c2);
$framework = $lpg->create_framework();
$comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'))); // In C1, and C2.
$comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'))); // In C2.
$comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'))); // In None.
$comp4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'))); // In C4.
$lpg->create_course_competency(array('competencyid' => $comp1->get('id'), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp1->get('id'), 'courseid' => $c2->id));
$lpg->create_course_competency(array('competencyid' => $comp2->get('id'), 'courseid' => $c2->id));
$lpg->create_course_competency(array('competencyid' => $comp4->get('id'), 'courseid' => $c4->id));
// Enrol the user 1 in C1, C2, and C3.
$dg->enrol_user($u1->id, $c1->id);
$dg->enrol_user($u1->id, $c2->id);
$dg->enrol_user($u1->id, $c3->id);
// Enrol the user 2 in C4.
$dg->enrol_user($u2->id, $c4->id);
// Enrol the user 3 in C1 and C2, but non active in C2.
$dg->enrol_user($u3->id, $c1->id);
$dg->enrol_user($u3->id, $c2->id, null, 'manual', 0, 0, ENROL_USER_SUSPENDED);
// Enrol the user 4 with a plugin which will be enabled/disabled.
$dg->enrol_user($u4->id, $c2->id, null, 'flatfile');
// Using the competency that is not used anywhere -> no courses.
$this->assertCount(0, course_competency::get_courses_with_competency_and_user($comp3->get('id'), $u1->id));
// Using the competency that is used in a course where the user is not enrolled -> no courses.
$this->assertCount(0, course_competency::get_courses_with_competency_and_user($comp4->get('id'), $u1->id));
// Using the competency that is used in a course where the user is enrolled -> one course.
$courses = course_competency::get_courses_with_competency_and_user($comp2->get('id'), $u1->id);
$this->assertCount(1, $courses);
$this->assertArrayHasKey($c2->id, $courses);
// Using the competency used multiple times.
$courses = course_competency::get_courses_with_competency_and_user($comp1->get('id'), $u1->id);
$this->assertCount(2, $courses);
$this->assertArrayHasKey($c1->id, $courses);
$this->assertArrayHasKey($c2->id, $courses);
// Checking for another user where the competency is used twice, but not for them.
$courses = course_competency::get_courses_with_competency_and_user($comp1->get('id'), $u2->id);
$this->assertCount(0, $courses);
// Checking for another user where the competency is used in their course.
$courses = course_competency::get_courses_with_competency_and_user($comp4->get('id'), $u2->id);
$this->assertCount(1, $courses);
$this->assertArrayHasKey($c4->id, $courses);
// Checking for a user who is suspended in a course.
$courses = course_competency::get_courses_with_competency_and_user($comp1->get('id'), $u3->id);
$this->assertCount(1, $courses);
$this->assertArrayHasKey($c1->id, $courses);
// Check for the user with plugin enabled.
$enrolplugins = explode(',', $CFG->enrol_plugins_enabled);
$enrolplugins[] = 'flatfile';
$CFG->enrol_plugins_enabled = implode(',', array_unique($enrolplugins));
$courses = course_competency::get_courses_with_competency_and_user($comp1->get('id'), $u4->id);
$this->assertCount(1, $courses);
$this->assertArrayHasKey($c2->id, $courses);
// Check for the user with plugin enabled, but enrolment instance disabled.
$flatfileinstance = $DB->get_record('enrol', array('id' => $flatfileinstanceid));
$flatfileplugin->update_status($flatfileinstance, ENROL_INSTANCE_DISABLED);
$courses = course_competency::get_courses_with_competency_and_user($comp1->get('id'), $u4->id);
$this->assertCount(0, $courses);
$flatfileplugin->update_status($flatfileinstance, ENROL_INSTANCE_ENABLED);
// Check for the user with plugin disabled.
$enrolplugins = array_flip(explode(',', $CFG->enrol_plugins_enabled));
unset($enrolplugins['flatfile']);
$CFG->enrol_plugins_enabled = implode(',', array_keys($enrolplugins));
$courses = course_competency::get_courses_with_competency_and_user($comp1->get('id'), $u4->id);
$this->assertCount(0, $courses);
}
}
@@ -0,0 +1,61 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Course module competency persistent testcase.
*
* @package core_competency
* @copyright 2019 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_competency_test extends \advanced_testcase {
public function test_count_competencies(): void {
global $CFG, $DB;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$c1 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$framework = $lpg->create_framework();
$comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'))); // In C1, and C2.
$comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'))); // In C2.
$lpg->create_course_competency(array('competencyid' => $comp1->get('id'), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp2->get('id'), 'courseid' => $c1->id));
$assign1a = $dg->create_module('assign', ['course' => $c1]);
$assign1b = $dg->create_module('assign', ['course' => $c1]);
$cmc1a = $lpg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1a->cmid]);
$cmc1b = $lpg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1b->cmid]);
$cmc2b = $lpg->create_course_module_competency(['competencyid' => $comp2->get('id'), 'cmid' => $assign1b->cmid]);
// Enrol the user 1 in C1.
$dg->enrol_user($u1->id, $c1->id);
$all = course_module_competency::list_course_module_competencies($assign1a->cmid);
$this->assertEquals(course_module_competency::count_competencies($assign1a->cmid), count($all));
$all = course_module_competency::list_course_module_competencies($assign1b->cmid);
$this->assertEquals(course_module_competency::count_competencies($assign1b->cmid), count($all));
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,261 @@
<?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/>.
use core_competency\competency;
use core_competency\competency_framework;
use core_competency\plan;
/**
* Behat data generator for core_competency.
*
* @package core_competency
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_core_competency_generator extends behat_generator_base {
/**
* Get a list of the entities that Behat can create using the generator step.
*
* @return array
*/
protected function get_creatable_entities(): array {
return [
'competencies' => [
'singular' => 'competency',
'datagenerator' => 'competency',
'required' => ['shortname', 'competencyframework'],
'switchids' => ['competencyframework' => 'competencyframeworkid'],
],
'course_competencies' => [
'singular' => 'course_competency',
'datagenerator' => 'course_competency',
'required' => ['course', 'competency'],
'switchids' => ['course' => 'courseid', 'competency' => 'competencyid'],
],
'frameworks' => [
'singular' => 'framework',
'datagenerator' => 'framework',
'required' => ['shortname'],
'switchids' => ['scale' => 'scaleid'],
],
'plans' => [
'singular' => 'plan',
'datagenerator' => 'plan',
'required' => ['name'],
'switchids' => ['user' => 'userid'],
],
'related_competencies' => [
'singular' => 'related_competency',
'datagenerator' => 'related_competency',
'required' => ['competency', 'relatedcompetency'],
'switchids' => ['competency' => 'competencyid', 'relatedcompetency' => 'relatedcompetencyid'],
],
'user_competency' => [
'singular' => 'user_competency',
'datagenerator' => 'user_competency',
'required' => ['competency', 'user'],
'switchids' => ['competency' => 'competencyid', 'user' => 'userid'],
],
'user_competency_courses' => [
'singular' => 'user_competency_course',
'datagenerator' => 'user_competency_course',
'required' => ['course', 'competency', 'user'],
'switchids' => ['course' => 'courseid', 'competency' => 'competencyid', 'user' => 'userid'],
],
'user_competency_plans' => [
'singular' => 'user_competency_plan',
'datagenerator' => 'user_competency_plan',
'required' => ['plan', 'competency', 'user'],
'switchids' => ['plan' => 'planid', 'competency' => 'competencyid', 'user' => 'userid'],
],
];
}
/**
* Get the competecy framework id using an idnumber.
*
* @param string $idnumber
* @return int The competecy framework id
*/
protected function get_competencyframework_id(string $idnumber): int {
global $DB;
if (!$id = $DB->get_field('competency_framework', 'id', ['idnumber' => $idnumber])) {
throw new Exception('The specified competency framework with idnumber "' . $idnumber . '" could not be found.');
}
return $id;
}
/**
* Get the competecy id using an idnumber.
*
* @param string $idnumber
* @return int The competecy id
*/
protected function get_competency_id(string $idnumber): int {
global $DB;
if (!$id = $DB->get_field('competency', 'id', ['idnumber' => $idnumber])) {
throw new Exception('The specified competency with idnumber "' . $idnumber . '" could not be found.');
}
return $id;
}
/**
* Get the learning plan id using a name.
*
* @param string $name
* @return int The learning plan id
*/
protected function get_plan_id(string $name): int {
global $DB;
if (!$id = $DB->get_field('competency_plan', 'id', ['name' => $name])) {
throw new Exception('The specified learning plan with name "' . $name . '" could not be found.');
}
return $id;
}
/**
* Get the related competecy id using an idnumber.
*
* @param string $idnumber
* @return int The related competecy id
*/
protected function get_relatedcompetency_id(string $idnumber): int {
return $this->get_competency_id($idnumber);
}
/**
* Add a plan.
*
* @param array $data Plan data.
*/
public function process_plan(array $data): void {
$generator = $this->get_data_generator();
$competencyids = $data['competencyids'] ?? [];
unset($data['competencyids']);
$plan = $generator->create_plan($data);
foreach ($competencyids as $competencyid) {
$generator->create_plan_competency([
'planid' => $plan->get('id'),
'competencyid' => $competencyid,
]);
}
}
/**
* Preprocess user competency data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_user_competency(array $data): array {
$this->prepare_grading($data);
return $data;
}
/**
* Preprocess user course competency data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_user_competency_course(array $data): array {
$this->prepare_grading($data);
return $data;
}
/**
* Preprocess user learning plan competency data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_user_competency_plan(array $data): array {
$this->prepare_grading($data);
return $data;
}
/**
* Preprocess plan data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_plan(array $data): array {
if (isset($data['competencies'])) {
$competencies = array_map('trim', str_getcsv($data['competencies']));
$data['competencyids'] = array_map([$this, 'get_competency_id'], $competencies);
unset($data['competencies']);
}
global $USER;
return $data + [
'userid' => $USER->id,
'status' => plan::STATUS_ACTIVE,
];
}
/**
* Prepare grading attributes for record data.
*
* @param array $data Record data.
*/
protected function prepare_grading(array &$data): void {
if (!isset($data['grade'])) {
return;
}
global $DB;
$competency = competency::get_record(['id' => $data['competencyid']]);
$competencyframework = competency_framework::get_record(['id' => $competency->get('competencyframeworkid')]);
$scale = $DB->get_field('scale', 'scale', ['id' => $competencyframework->get('scaleid')]);
$grades = array_map('trim', explode(',', $scale));
$grade = array_search($data['grade'], $grades);
if ($grade === false) {
throw new Exception('The grade "'.$data['grade'].'" was not found in the "'.
$competencyframework->get('shortname').'" competency framework.');
}
$data['proficiency'] = true;
$data['grade'] = $grade + 1;
}
/**
* Get the module data generator.
*
* @return core_competency_generator Competency data generator.
*/
protected function get_data_generator(): core_competency_generator {
return $this->componentdatagenerator;
}
}
+590
View File
@@ -0,0 +1,590 @@
<?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/>.
/**
* Competency data generator.
*
* @package core_competency
* @category test
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_competency\competency;
use core_competency\competency_framework;
use core_competency\course_competency;
use core_competency\course_module_competency;
use core_competency\evidence;
use core_competency\external;
use core_competency\plan;
use core_competency\plan_competency;
use core_competency\related_competency;
use core_competency\template;
use core_competency\template_cohort;
use core_competency\template_competency;
use core_competency\user_competency;
use core_competency\user_competency_course;
use core_competency\user_competency_plan;
use core_competency\user_evidence;
use core_competency\user_evidence_competency;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/grade/grade_scale.php');
/**
* Competency data generator class.
*
* @package core_competency
* @category test
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_competency_generator extends component_generator_base {
/** @var int Number of created competencies. */
protected $competencycount = 0;
/** @var int Number of created frameworks. */
protected $frameworkcount = 0;
/** @var int Number of created plans. */
protected $plancount = 0;
/** @var int Number of created templates. */
protected $templatecount = 0;
/** @var int Number of created user_evidence. */
protected $userevidencecount = 0;
/** @var stdClass Scale that we might need. */
protected $scale;
/**
* Reset process.
*
* Do not call directly.
*
* @return void
*/
public function reset() {
$this->competencycount = 0;
$this->frameworkcount = 0;
$this->scale = null;
}
/**
* Create a new competency.
*
* @param array|stdClass $record
* @return competency
*/
public function create_competency($record = null) {
$this->competencycount++;
$i = $this->competencycount;
$record = (object) $record;
if (!isset($record->competencyframeworkid)) {
throw new coding_exception('The competencyframeworkid value is required.');
}
if (!isset($record->shortname)) {
$record->shortname = "Competency shortname $i";
}
if (!isset($record->idnumber)) {
$record->idnumber = "cmp{$i}";
}
if (!isset($record->description)) {
$record->description = "Competency $i description ";
}
if (!isset($record->descriptionformat)) {
$record->descriptionformat = FORMAT_HTML;
}
if (!isset($record->scaleconfiguration) && isset($record->scaleid)) {
$record->scaleconfiguration = json_encode($this->make_default_scale_configuration($record->scaleid));
}
if (isset($record->scaleconfiguration)
&& (is_array($record->scaleconfiguration) || is_object($record->scaleconfiguration))) {
// Conveniently encode the config.
$record->scaleconfiguration = json_encode($record->scaleconfiguration);
}
$competency = new competency(0, $record);
$competency->create();
return $competency;
}
/**
* Create a new framework.
*
* @param array|stdClass $record
* @return competency_framework
*/
public function create_framework($record = null) {
if (defined('BEHAT_TEST') && BEHAT_TEST) {
$generator = behat_util::get_data_generator();
} else {
$generator = phpunit_util::get_data_generator();
}
$this->frameworkcount++;
$i = $this->frameworkcount;
$record = (object) $record;
if (!isset($record->shortname)) {
$record->shortname = "Framework shortname $i";
}
if (!isset($record->idnumber)) {
$record->idnumber = "frm{$i}";
}
if (!isset($record->description)) {
$record->description = "Framework $i description ";
}
if (!isset($record->descriptionformat)) {
$record->descriptionformat = FORMAT_HTML;
}
if (!isset($record->visible)) {
$record->visible = 1;
}
if (!isset($record->scaleid)) {
if (isset($record->scaleconfiguration)) {
throw new coding_exception('Scale configuration must be provided with a scale.');
}
if (!$this->scale) {
$this->scale = $generator->create_scale(array('scale' => 'A,B,C,D'));
}
$record->scaleid = $this->scale->id;
}
if (!isset($record->scaleconfiguration)) {
$record->scaleconfiguration = json_encode($this->make_default_scale_configuration($record->scaleid));
}
if (is_array($record->scaleconfiguration) || is_object($record->scaleconfiguration)) {
// Conveniently encode the config.
$record->scaleconfiguration = json_encode($record->scaleconfiguration);
}
if (!isset($record->contextid)) {
$record->contextid = context_system::instance()->id;
}
$framework = new competency_framework(0, $record);
$framework->create();
return $framework;
}
/**
* Create a related competency.
*
* @param array|stdClass $record
* @return related_competency
*/
public function create_related_competency($record = null) {
$record = (object) $record;
if (!isset($record->competencyid)) {
throw new coding_exception('Property competencyid is required.');
}
if (!isset($record->relatedcompetencyid)) {
throw new coding_exception('Property relatedcompetencyid is required.');
}
$relation = related_competency::get_relation($record->competencyid, $record->relatedcompetencyid);
if ($relation->get('id')) {
throw new coding_exception('Relation already exists');
}
$relation->create();
return $relation;
}
/**
* Create a template.
*
* @param array|stdClass $record
* @return template
*/
public function create_template($record = null) {
$this->templatecount++;
$i = $this->templatecount;
$record = (object) $record;
if (!isset($record->shortname)) {
$record->shortname = "Template shortname $i";
}
if (!isset($record->description)) {
$record->description = "Template $i description ";
}
if (!isset($record->contextid)) {
$record->contextid = context_system::instance()->id;
}
$template = new template(0, $record);
$template->create();
return $template;
}
/**
* Create a template competency.
*
* @param array|stdClass $record
* @return template_competency
*/
public function create_template_competency($record = null) {
$record = (object) $record;
if (!isset($record->competencyid)) {
throw new coding_exception('Property competencyid is required.');
}
if (!isset($record->templateid)) {
throw new coding_exception('Property templateid is required.');
}
$relation = new template_competency(0, $record);
$relation->create();
return $relation;
}
/**
* Create a new user competency.
*
* @param array|stdClass $record
* @return user_competency
*/
public function create_user_competency($record = null) {
$record = (object) $record;
if (!isset($record->userid)) {
throw new coding_exception('The userid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
$usercompetency = new user_competency(0, $record);
$usercompetency->create();
return $usercompetency;
}
/**
* Create a new plan.
*
* @param array|stdClass $record
* @return plan
*/
public function create_plan($record = null) {
$this->plancount++;
$i = $this->plancount;
$record = (object) $record;
if (!isset($record->name)) {
$record->name = "Plan shortname $i";
}
if (!isset($record->description)) {
$record->description = "Plan $i description";
}
if (!isset($record->descriptionformat)) {
$record->descriptionformat = FORMAT_HTML;
}
if (!isset($record->userid)) {
throw new coding_exception('The userid value is required.');
}
$plan = new plan(0, $record);
$plan->create();
return $plan;
}
/**
* Create a new user competency course.
*
* @param array|stdClass $record
* @return user_competency_course
*/
public function create_user_competency_course($record = null) {
$record = (object) $record;
if (!isset($record->userid)) {
throw new coding_exception('The userid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
if (!isset($record->courseid)) {
throw new coding_exception('The courseid value is required.');
}
$usercompetencycourse = new user_competency_course(0, $record);
$usercompetencycourse->create();
return $usercompetencycourse;
}
/**
* Create a new user competency plan.
*
* @param array|stdClass $record
* @return user_competency_plan
*/
public function create_user_competency_plan($record = null) {
$record = (object) $record;
if (!isset($record->userid)) {
throw new coding_exception('The userid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
if (!isset($record->planid)) {
throw new coding_exception('The planid value is required.');
}
if (!isset($record->sortorder)) {
$record->sortorder = 0;
}
$usercompetencyplan = new user_competency_plan(0, $record);
$usercompetencyplan->create();
return $usercompetencyplan;
}
/**
* Create a new plan competency.
*
* @param array|stdClass $record
* @return plan_competency
*/
public function create_plan_competency($record = null) {
$record = (object) $record;
if (!isset($record->planid)) {
throw new coding_exception('The planid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
$plancompetency = new plan_competency(0, $record);
$plancompetency->create();
return $plancompetency;
}
/**
* Create a new template cohort.
*
* @param array|stdClass $record
* @return template_cohort
*/
public function create_template_cohort($record = null) {
$record = (object) $record;
if (!isset($record->templateid)) {
throw new coding_exception('The templateid value is required.');
}
if (!isset($record->cohortid)) {
throw new coding_exception('The cohortid value is required.');
}
$tplcohort = new template_cohort(0, $record);
$tplcohort->create();
return $tplcohort;
}
/**
* Create a new evidence.
*
* @param array|stdClass $record
* @return evidence
*/
public function create_evidence($record = null) {
$record = (object) $record;
if (!isset($record->usercompetencyid)) {
throw new coding_exception('The usercompetencyid value is required.');
}
if (!isset($record->action) && !isset($record->grade)) {
$record->action = evidence::ACTION_LOG;
}
if (!isset($record->action)) {
throw new coding_exception('The action value is required with a grade.');
}
if (!isset($record->contextid)) {
$record->contextid = context_system::instance()->id;
}
if (!isset($record->descidentifier)) {
$record->descidentifier = 'invalidevidencedesc';
}
if (!isset($record->desccomponent)) {
$record->desccomponent = 'core_competency';
}
$evidence = new evidence(0, $record);
$evidence->create();
return $evidence;
}
/**
* Create a new course competency.
*
* @param array|stdClass $record
* @return user_competency
*/
public function create_course_competency($record = null) {
$record = (object) $record;
if (!isset($record->courseid)) {
throw new coding_exception('The courseid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
$cc = new course_competency(0, $record);
$cc->create();
return $cc;
}
/**
* Create a new course module competency.
*
* @param array|stdClass $record
* @return course_module_competency
*/
public function create_course_module_competency($record = null) {
$record = (object) $record;
if (!isset($record->cmid)) {
throw new coding_exception('The cmid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
$cc = new course_module_competency(0, $record);
$cc->create();
return $cc;
}
/**
* Create a new user_evidence.
*
* @param array|stdClass $record
* @return evidence
*/
public function create_user_evidence($record = null) {
$this->userevidencecount++;
$i = $this->userevidencecount;
$record = (object) $record;
if (!isset($record->userid)) {
throw new coding_exception('The userid value is required.');
}
if (!isset($record->name)) {
$record->name = "Evidence $i name";
}
if (!isset($record->description)) {
$record->description = "Evidence $i description";
}
if (!isset($record->descriptionformat)) {
$record->descriptionformat = FORMAT_HTML;
}
$ue = new user_evidence(0, $record);
$ue->create();
return $ue;
}
/**
* Create a new user_evidence_comp.
*
* @param array|stdClass $record
* @return evidence
*/
public function create_user_evidence_competency($record = null) {
$record = (object) $record;
if (!isset($record->userevidenceid)) {
throw new coding_exception('The userevidenceid value is required.');
}
if (!isset($record->competencyid)) {
throw new coding_exception('The competencyid value is required.');
}
$uec = new user_evidence_competency(0, $record);
$uec->create();
return $uec;
}
/**
* Make a default scale configuration.
*
* The last and second-last item will be flagged proficient. The
* second-last item will be flagged as default.
*
* @param int $scaleid The scale ID.
* @return array Configuration as array.
*/
protected function make_default_scale_configuration($scaleid) {
$scale = grade_scale::fetch(array('id' => $scaleid));
$values = $scale->load_items();
foreach ($values as $key => $value) {
// Add a key (make the first value 1).
$values[$key] = array('id' => $key + 1, 'name' => $value);
}
if (count($values) < 2) {
throw new coding_exception('Please provide the scale configuration for one-item scales.');
}
$scaleconfig = array();
// Last item is proficient.
$item = array_pop($values);
array_unshift($scaleconfig, array(
'id' => $item['id'],
'proficient' => 1
));
// Second-last item is default and proficient.
$item = array_pop($values);
array_unshift($scaleconfig, array(
'id' => $item['id'],
'scaledefault' => 1,
'proficient' => 1
));
// Add the scale ID.
array_unshift($scaleconfig, array('scaleid' => $scaleid));
return $scaleconfig;
}
}
+237
View File
@@ -0,0 +1,237 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Tool LP data generator testcase.
*
* @package core_competency
* @category test
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class generator_test extends \advanced_testcase {
public function test_create_framework(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$this->assertEquals(0, competency_framework::count_records());
$framework = $lpg->create_framework();
$framework = $lpg->create_framework();
$this->assertEquals(2, competency_framework::count_records());
$this->assertInstanceOf('\core_competency\competency_framework', $framework);
}
public function test_create_competency(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$framework = $lpg->create_framework();
$this->assertEquals(0, competency::count_records());
$competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$this->assertEquals(2, competency::count_records());
$this->assertInstanceOf('\core_competency\competency', $competency);
}
public function test_create_related_competency(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$framework = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$this->assertEquals(0, related_competency::count_records());
$rc = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c2->get('id')));
$rc = $lpg->create_related_competency(array('competencyid' => $c2->get('id'), 'relatedcompetencyid' => $c3->get('id')));
$this->assertEquals(2, related_competency::count_records());
$this->assertInstanceOf('\core_competency\related_competency', $rc);
}
public function test_create_plan(): void {
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$this->assertEquals(0, plan::count_records());
$plan = $lpg->create_plan(array('userid' => $user->id));
$this->assertEquals(1, plan::count_records());
$this->assertInstanceOf('\core_competency\plan', $plan);
}
public function test_create_user_competency(): void {
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$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')));
$this->assertEquals(0, user_competency::count_records());
$rc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get('id')));
$rc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get('id')));
$this->assertEquals(2, user_competency::count_records());
$this->assertInstanceOf('\core_competency\user_competency', $rc);
}
public function test_create_user_competency_plan(): void {
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$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')));
$plan = $lpg->create_plan(array('userid' => $user->id));
$this->assertEquals(0, user_competency_plan::count_records());
$ucp = $lpg->create_user_competency_plan(array(
'userid' => $user->id,
'competencyid' => $c1->get('id'),
'planid' => $plan->get('id')
));
$ucp = $lpg->create_user_competency_plan(array(
'userid' => $user->id,
'competencyid' => $c2->get('id'),
'planid' => $plan->get('id')
));
$this->assertEquals(2, user_competency_plan::count_records());
$this->assertInstanceOf('\core_competency\user_competency_plan', $ucp);
}
public function test_create_template(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$this->assertEquals(0, template::count_records());
$template = $lpg->create_template();
$template = $lpg->create_template();
$this->assertEquals(2, template::count_records());
$this->assertInstanceOf('\core_competency\template', $template);
}
public function test_create_template_competency(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$this->assertEquals(0, template_competency::count_records());
$framework = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
$template = $lpg->create_template();
$relation = $lpg->create_template_competency(array('competencyid' => $c1->get('id'), 'templateid' => $template->get('id')));
$relation = $lpg->create_template_competency(array('competencyid' => $c2->get('id'), 'templateid' => $template->get('id')));
$this->assertEquals(2, template_competency::count_records());
$this->assertInstanceOf('\core_competency\template_competency', $relation);
}
public function test_create_plan_competency(): void {
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$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')));
$plan = $lpg->create_plan(array('userid' => $user->id));
$pc1 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $c1->get('id')));
$pc2 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $c2->get('id')));
$this->assertEquals(2, plan_competency::count_records());
$this->assertInstanceOf('\core_competency\plan_competency', $pc1);
$this->assertInstanceOf('\core_competency\plan_competency', $pc2);
$this->assertEquals($plan->get('id'), $pc1->get('planid'));
}
public function test_create_template_cohort(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$c1 = $this->getDataGenerator()->create_cohort();
$c2 = $this->getDataGenerator()->create_cohort();
$t1 = $lpg->create_template();
$this->assertEquals(0, template_cohort::count_records());
$tc = $lpg->create_template_cohort(array('templateid' => $t1->get('id'), 'cohortid' => $c1->id));
$this->assertEquals(1, template_cohort::count_records());
$tc = $lpg->create_template_cohort(array('templateid' => $t1->get('id'), 'cohortid' => $c2->id));
$this->assertEquals(2, template_cohort::count_records());
$this->assertInstanceOf('\core_competency\template_cohort', $tc);
}
public function test_create_evidence(): void {
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$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')));
$rc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get('id')));
$rc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get('id')));
$e = $lpg->create_evidence(array('usercompetencyid' => $rc1->get('id')));
$e = $lpg->create_evidence(array('usercompetencyid' => $rc2->get('id')));
$this->assertEquals(2, evidence::count_records());
$this->assertInstanceOf('\core_competency\evidence', $e);
}
public function test_create_course_competency(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->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')));
$this->assertEquals(0, course_competency::count_records());
$rc = $lpg->create_course_competency(array('competencyid' => $c1->get('id'), 'courseid' => $course1->id));
$rc = $lpg->create_course_competency(array('competencyid' => $c2->get('id'), 'courseid' => $course1->id));
$this->assertEquals(2, course_competency::count_records(array('courseid' => $course1->id)));
$this->assertEquals(0, course_competency::count_records(array('courseid' => $course2->id)));
$rc = $lpg->create_course_competency(array('competencyid' => $c3->get('id'), 'courseid' => $course2->id));
$this->assertEquals(1, course_competency::count_records(array('courseid' => $course2->id)));
$this->assertInstanceOf('\core_competency\course_competency', $rc);
}
public function test_create_course_module_competency(): void {
$this->resetAfterTest(true);
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$course1 = $this->getDataGenerator()->create_course();
$cm1 = $this->getDataGenerator()->create_module('forum', array('course' => $course1->id));
$cm2 = $this->getDataGenerator()->create_module('forum', array('course' => $course1->id));
$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')));
$this->assertEquals(0, course_module_competency::count_records());
$rc = $lpg->create_course_module_competency(array('competencyid' => $c1->get('id'), 'cmid' => $cm1->cmid));
$rc = $lpg->create_course_module_competency(array('competencyid' => $c2->get('id'), 'cmid' => $cm1->cmid));
$this->assertEquals(2, course_module_competency::count_records(array('cmid' => $cm1->cmid)));
$this->assertEquals(0, course_module_competency::count_records(array('cmid' => $cm2->cmid)));
$rc = $lpg->create_course_module_competency(array('competencyid' => $c3->get('id'), 'cmid' => $cm2->cmid));
$this->assertEquals(1, course_module_competency::count_records(array('cmid' => $cm2->cmid)));
$this->assertInstanceOf('\core_competency\course_module_competency', $rc);
}
}
+241
View File
@@ -0,0 +1,241 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Hook 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
*/
class hooks_test extends \advanced_testcase {
public function test_hook_course_deleted(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$ccg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$framework = $ccg->create_framework();
$comp1 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$comp2 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$c1 = $dg->create_course();
$cc1a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id]);
$cc1b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id]);
$assign1a = $dg->create_module('assign', ['course' => $c1]);
$assign1b = $dg->create_module('assign', ['course' => $c1]);
$cmc1a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1a->cmid]);
$cmc1b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1b->cmid]);
$ucc1a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$ucc1b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$c2 = $dg->create_course();
$cc2a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id]);
$cc2b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id]);
$assign2a = $dg->create_module('assign', ['course' => $c2]);
$assign2b = $dg->create_module('assign', ['course' => $c2]);
$cmc2a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2a->cmid]);
$cmc2b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2b->cmid]);
$ucc2a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
$ucc2b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
delete_course($c1, false);
$this->assertEquals(0, course_competency::count_records(['courseid' => $c1->id]));
$this->assertEquals(2, course_competency::count_records(['courseid' => $c2->id]));
$this->assertEquals(0, course_module_competency::count_records(['cmid' => $assign1a->cmid]));
$this->assertEquals(0, course_module_competency::count_records(['cmid' => $assign1b->cmid]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2a->cmid]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2b->cmid]));
$this->assertEquals(0, user_competency_course::count_records(['courseid' => $c1->id, 'userid' => $u1->id]));
$this->assertEquals(2, user_competency_course::count_records(['courseid' => $c2->id, 'userid' => $u1->id]));
}
public function test_hook_course_module_deleted(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$ccg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$framework = $ccg->create_framework();
$comp1 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$comp2 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$c1 = $dg->create_course();
$cc1a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id]);
$cc1b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id]);
$assign1a = $dg->create_module('assign', ['course' => $c1]);
$assign1b = $dg->create_module('assign', ['course' => $c1]);
$cmc1a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1a->cmid]);
$cmc1b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1b->cmid]);
$ucc1a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$ucc1b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$c2 = $dg->create_course();
$cc2a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id]);
$cc2b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id]);
$assign2a = $dg->create_module('assign', ['course' => $c2]);
$assign2b = $dg->create_module('assign', ['course' => $c2]);
$cmc2a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2a->cmid]);
$cmc2b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2b->cmid]);
$ucc2a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
$ucc2b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
course_delete_module($assign1b->cmid);
$this->assertEquals(2, course_competency::count_records(['courseid' => $c1->id]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign1a->cmid]));
$this->assertEquals(0, course_module_competency::count_records(['cmid' => $assign1b->cmid]));
$this->assertEquals(2, user_competency_course::count_records(['courseid' => $c1->id]));
$this->assertEquals(2, course_competency::count_records(['courseid' => $c2->id]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2a->cmid]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2b->cmid]));
$this->assertEquals(2, user_competency_course::count_records(['courseid' => $c2->id, 'userid' => $u1->id]));
}
public function test_hook_course_reset_competency_ratings(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$ccg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$framework = $ccg->create_framework();
$comp1 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$comp2 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$c1 = $dg->create_course();
$cc1a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id]);
$cc1b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id]);
$assign1a = $dg->create_module('assign', ['course' => $c1]);
$assign1b = $dg->create_module('assign', ['course' => $c1]);
$cmc1a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1a->cmid]);
$cmc1b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1b->cmid]);
$ucc1a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$ucc1b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$c2 = $dg->create_course();
$cc2a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id]);
$cc2b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id]);
$assign2a = $dg->create_module('assign', ['course' => $c2]);
$assign2b = $dg->create_module('assign', ['course' => $c2]);
$cmc2a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2a->cmid]);
$cmc2b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2b->cmid]);
$ucc2a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
$ucc2b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
reset_course_userdata((object) ['id' => $c1->id, 'reset_competency_ratings' => true]);
$this->assertEquals(2, course_competency::count_records(['courseid' => $c1->id]));
$this->assertEquals(2, course_competency::count_records(['courseid' => $c2->id]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign1a->cmid]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign1b->cmid]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2a->cmid]));
$this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2b->cmid]));
$this->assertEquals(0, user_competency_course::count_records(['courseid' => $c1->id, 'userid' => $u1->id]));
$this->assertEquals(2, user_competency_course::count_records(['courseid' => $c2->id, 'userid' => $u1->id]));
}
public function test_hook_cohort_deleted(): void {
$this->resetAfterTest();
$this->setAdminUser();
$datagen = $this->getDataGenerator();
$corecompgen = $datagen->get_plugin_generator('core_competency');
$c1 = $datagen->create_cohort();
$c2 = $datagen->create_cohort();
$t1 = $corecompgen->create_template();
$t2 = $corecompgen->create_template();
// Create the template cohorts.
api::create_template_cohort($t1->get('id'), $c1->id);
api::create_template_cohort($t1->get('id'), $c2->id);
api::create_template_cohort($t2->get('id'), $c1->id);
// Check that the association was made.
$this->assertEquals(2, \core_competency\template_cohort::count_records(array('templateid' => $t1->get('id'))));
$this->assertEquals(1, \core_competency\template_cohort::count_records(array('templateid' => $t2->get('id'))));
// Delete the first cohort.
cohort_delete_cohort($c1);
// Check that the association was removed.
$this->assertEquals(1, \core_competency\template_cohort::count_records(array('templateid' => $t1->get('id'))));
$this->assertEquals(0, \core_competency\template_cohort::count_records(array('templateid' => $t2->get('id'))));
}
public function test_hook_user_deleted(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$ccg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$framework = $ccg->create_framework();
$comp1 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$comp2 = $ccg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$c1 = $dg->create_course();
$cc1a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id]);
$cc1b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id]);
$assign1a = $dg->create_module('assign', ['course' => $c1]);
$assign1b = $dg->create_module('assign', ['course' => $c1]);
$cmc1a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1a->cmid]);
$cmc1b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign1b->cmid]);
$ucc1a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$ucc1b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c1->id,
'userid' => $u1->id]);
$c2 = $dg->create_course();
$cc2a = $ccg->create_course_competency(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id]);
$cc2b = $ccg->create_course_competency(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id]);
$assign2a = $dg->create_module('assign', ['course' => $c2]);
$assign2b = $dg->create_module('assign', ['course' => $c2]);
$cmc2a = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2a->cmid]);
$cmc2b = $ccg->create_course_module_competency(['competencyid' => $comp1->get('id'), 'cmid' => $assign2b->cmid]);
$ucc2a = $ccg->create_user_competency_course(['competencyid' => $comp1->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
$ucc2b = $ccg->create_user_competency_course(['competencyid' => $comp2->get('id'), 'courseid' => $c2->id,
'userid' => $u1->id]);
reset_course_userdata((object) ['id' => $c1->id, 'reset_competency_ratings' => true]);
delete_user($u1);
// Assert the records don't exist anymore.
$this->assertEquals(0, user_competency_course::count_records(['courseid' => $c1->id, 'userid' => $u1->id]));
}
}
+319
View File
@@ -0,0 +1,319 @@
<?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/>.
/**
* Lib tests.
*
* @package core_competency
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_competency;
defined('MOODLE_INTERNAL') || die();
use core_competency\plan;
use core_competency\url;
use core_competency\user_competency;
global $CFG;
/**
* Lib testcase.
*
* @package core_competency
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class lib_test extends \advanced_testcase {
public function test_comment_add_user_competency(): void {
global $DB, $PAGE;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user(['picture' => 1]);
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$reviewerroleid = $dg->create_role();
assign_capability('moodle/competency:planview', CAP_ALLOW, $reviewerroleid, \context_system::instance()->id, true);
assign_capability('moodle/competency:usercompetencycomment', CAP_ALLOW, $reviewerroleid,
\context_system::instance()->id, true);
$dg->role_assign($reviewerroleid, $u2->id, \context_user::instance($u1->id));
$dg->role_assign($reviewerroleid, $u3->id, \context_user::instance($u1->id));
accesslib_clear_all_caches_for_unit_testing();
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'))); // In 1 plan.
$c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'))); // In 2 plans.
$c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'))); // Orphan.
$p1 = $lpg->create_plan(array('userid' => $u1->id));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c1->get('id')));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c2->get('id')));
$p2 = $lpg->create_plan(array('userid' => $u1->id));
$lpg->create_plan_competency(array('planid' => $p2->get('id'), 'competencyid' => $c2->get('id')));
$DB->set_field(plan::TABLE, 'timemodified', 1, array('id' => $p1->get('id'))); // Make plan 1 appear as old.
$p1->read();
$uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c1->get('id'),
'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $u2->id));
$uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c2->get('id'),
'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $u2->id));
$uc3 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get('id'),
'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $u2->id));
// Post a comment for the user competency being in one plan. The reviewer is messaged.
$this->setUser($u1);
$comment = $uc1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$expectedurlname = $c1->get('shortname');
$expectedurl = url::user_competency_in_plan($u1->id, $c1->get('id'), $p1->get('id'));
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u2->id, $message->useridto);
$this->assertTrue(strpos($message->fullmessage, 'Hello world!') !== false);
$this->assertTrue(strpos($message->fullmessagehtml, 'Hello world!') !== false);
$this->assertEquals(FORMAT_MOODLE, $message->fullmessageformat);
$this->assertEquals($expectedurl->out(false), $message->contexturl);
$this->assertEquals($expectedurlname, $message->contexturlname);
// Test customdata.
$customdata = json_decode($message->customdata);
$this->assertObjectHasProperty('notificationiconurl', $customdata);
$this->assertStringContainsString('tokenpluginfile.php', $customdata->notificationiconurl);
$userpicture = new \user_picture($u1);
$userpicture->size = 1; // Use f1 size.
$userpicture->includetoken = $u2->id;
$this->assertEquals($userpicture->get_url($PAGE)->out(false), $customdata->notificationiconurl);
// Reviewer posts a comment for the user competency being in two plans. Owner is messaged.
$this->setUser($u2);
$comment = $uc2->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$expectedurlname = $c2->get('shortname');
$expectedurl = url::user_competency_in_plan($u1->id, $c2->get('id'), $p2->get('id'));
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u1->id, $message->useridto);
$this->assertTrue(strpos($message->fullmessage, 'Hello world!') !== false);
$this->assertTrue(strpos($message->fullmessagehtml, 'Hello world!') !== false);
$this->assertEquals(FORMAT_MOODLE, $message->fullmessageformat);
$this->assertEquals($expectedurl->out(false), $message->contexturl);
$this->assertEquals($expectedurlname, $message->contexturlname);
// Reviewer posts a comment for the user competency being in no plans. User is messaged.
$this->setUser($u2);
$comment = $uc3->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$expectedurlname = get_string('userplans', 'core_competency');
$expectedurl = url::plans($u1->id);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u1->id, $message->useridto);
$this->assertTrue(strpos($message->fullmessage, 'Hello world!') !== false);
$this->assertTrue(strpos($message->fullmessagehtml, 'Hello world!') !== false);
$this->assertEquals(FORMAT_MOODLE, $message->fullmessageformat);
$this->assertEquals($expectedurl->out(false), $message->contexturl);
$this->assertEquals($expectedurlname, $message->contexturlname);
// A comment is posted by another user, reviewer and owner are messaged.
$this->setUser($u3);
$comment = $uc3->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(2, $messages);
$message1 = array_shift($messages);
$message2 = array_shift($messages);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u1->id, $message1->useridto);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u2->id, $message2->useridto);
// A comment is posted in HTML.
$this->setUser($u2);
$comment = $uc3->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('<em>Hello world!</em>', FORMAT_HTML);
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$expectedurlname = get_string('userplans', 'core_competency');
$expectedurl = url::plans($u1->id);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u1->id, $message->useridto);
$this->assertTrue(strpos($message->fullmessage, '<em>Hello world!</em>') !== false);
$this->assertTrue(strpos($message->fullmessagehtml, '<em>Hello world!</em>') !== false);
$this->assertEquals(FORMAT_HTML, $message->fullmessageformat);
$this->assertEquals($expectedurl->out(false), $message->contexturl);
$this->assertEquals($expectedurlname, $message->contexturlname);
}
/**
* Commenting on a plan.
*/
public function test_comment_add_plan(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$userroleid = $dg->create_role();
$reviewerroleid = $dg->create_role();
assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $userroleid, \context_system::instance()->id, true);
assign_capability('moodle/competency:planviewown', CAP_ALLOW, $userroleid, \context_system::instance()->id, true);
assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $reviewerroleid, \context_system::instance()->id, true);
assign_capability('moodle/competency:planmanage', CAP_ALLOW, $reviewerroleid, \context_system::instance()->id, true);
assign_capability('moodle/competency:plancomment', CAP_ALLOW, $reviewerroleid, \context_system::instance()->id, true);
$dg->role_assign($userroleid, $u1->id, \context_user::instance($u1->id));
$dg->role_assign($reviewerroleid, $u2->id, \context_user::instance($u1->id));
$dg->role_assign($reviewerroleid, $u3->id, \context_system::instance());
accesslib_clear_all_caches_for_unit_testing();
$p1 = $lpg->create_plan(array('userid' => $u1->id));
// Post a comment in own plan, no reviewer. Nobody is messaged.
$this->setUser($u1);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(0, $messages);
// Post a comment in plan as someone else, no reviewer. The owner is messages.
$this->setUser($u3);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u1->id, $message->useridto);
// Test customdata.
$customdata = json_decode($message->customdata);
$this->assertObjectHasProperty('notificationiconurl', $customdata);
// Post a comment in a plan with reviewer. The reviewer is messaged.
$p1->set('reviewerid', $u2->id);
$p1->update();
$this->setUser($u1);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u2->id, $message->useridto);
// Post a comment as reviewer in a plan being reviewed. The owner is messaged.
$p1->set('reviewerid', $u2->id);
$p1->update();
$this->setUser($u2);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$this->assertEquals(\core_user::get_noreply_user()->id, $message->useridfrom);
$this->assertEquals($u1->id, $message->useridto);
// Post a comment as someone else in a plan being reviewed. The owner and reviewer are messaged.
$p1->set('reviewerid', $u2->id);
$p1->update();
$this->setUser($u3);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(2, $messages);
$message1 = array_shift($messages);
$message2 = array_shift($messages);
$this->assertEquals(\core_user::get_noreply_user()->id, $message1->useridfrom);
$this->assertEquals($u1->id, $message1->useridto);
$this->assertEquals(\core_user::get_noreply_user()->id, $message2->useridfrom);
$this->assertEquals($u2->id, $message2->useridto);
$p1->set('reviewerid', null);
$p1->update();
// Test message content.
$this->setUser($u3);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('Hello world!');
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$expectedurlname = $p1->get('name');
$expectedurl = url::plan($p1->get('id'));
$this->assertTrue(strpos($message->fullmessage, 'Hello world!') !== false);
$this->assertTrue(strpos($message->fullmessagehtml, 'Hello world!') !== false);
$this->assertEquals(FORMAT_MOODLE, $message->fullmessageformat);
$this->assertEquals($expectedurl->out(false), $message->contexturl);
$this->assertEquals($expectedurlname, $message->contexturlname);
// Test message content as HTML.
$this->setUser($u3);
$comment = $p1->get_comment_object();
$sink = $this->redirectMessages();
$comment->add('<em>Hello world!</em>', FORMAT_HTML);
$messages = $sink->get_messages();
$sink->close();
$this->assertCount(1, $messages);
$message = array_pop($messages);
$expectedurlname = $p1->get('name');
$expectedurl = url::plan($p1->get('id'));
$this->assertTrue(strpos($message->fullmessage, '<em>Hello world!</em>') !== false);
$this->assertTrue(strpos($message->fullmessagehtml, '<em>Hello world!</em>') !== false);
$this->assertEquals(FORMAT_HTML, $message->fullmessageformat);
$this->assertEquals($expectedurl->out(false), $message->contexturl);
$this->assertEquals($expectedurlname, $message->contexturlname);
}
}
@@ -0,0 +1,150 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
use core_competency\external\performance_helper;
/**
* Performance helper 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 performance_helper_test extends \advanced_testcase {
public function test_get_context_from_competency(): void {
global $DB;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$cat1 = $dg->create_category();
$framework = $lpg->create_framework();
$competency = $lpg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$competency2 = $lpg->create_competency(['competencyframeworkid' => $framework->get('id')]);
$context = $competency->get_context();
$helper = new performance_helper();
$initdbqueries = $DB->perf_get_queries();
// Confirm that subsequent calls return a cached object.
// Note that here we check that the framework is not loaded more than once.
// The context objects are already cached in the context layer.
$firstruncontext = $helper->get_context_from_competency($competency);
$dbqueries = $DB->perf_get_queries();
$this->assertSame($context, $firstruncontext);
$this->assertNotEquals($initdbqueries, $dbqueries);
$secondruncontext = $helper->get_context_from_competency($competency);
$this->assertSame($context, $secondruncontext);
$this->assertSame($firstruncontext, $secondruncontext);
$this->assertEquals($DB->perf_get_queries(), $dbqueries);
$thirdruncontext = $helper->get_context_from_competency($competency2);
$this->assertSame($context, $thirdruncontext);
$this->assertSame($secondruncontext, $thirdruncontext);
$this->assertEquals($DB->perf_get_queries(), $dbqueries);
}
public function test_get_framework_from_competency(): void {
global $DB;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$cat1 = $dg->create_category();
$framework1 = $lpg->create_framework();
$comp1a = $lpg->create_competency(['competencyframeworkid' => $framework1->get('id')]);
$comp1b = $lpg->create_competency(['competencyframeworkid' => $framework1->get('id')]);
$framework2 = $lpg->create_framework();
$comp2a = $lpg->create_competency(['competencyframeworkid' => $framework2->get('id')]);
$helper = new performance_helper();
$initdbqueries = $DB->perf_get_queries();
// Confirm that we get the right framework, and that subsequent calls
// do not trigger DB queries, even for other competencies.
$firstrunframework = $helper->get_framework_from_competency($comp1a);
$firstrundbqueries = $DB->perf_get_queries();
$this->assertNotEquals($initdbqueries, $firstrundbqueries);
$this->assertEquals($framework1, $firstrunframework);
$this->assertNotSame($framework1, $firstrunframework);
$secondrunframework = $helper->get_framework_from_competency($comp1b);
$this->assertEquals($firstrundbqueries, $DB->perf_get_queries());
$this->assertEquals($framework1, $secondrunframework);
$this->assertSame($firstrunframework, $secondrunframework);
$thirdrunframework = $helper->get_framework_from_competency($comp1a);
$this->assertEquals($firstrundbqueries, $DB->perf_get_queries());
$this->assertEquals($framework1, $thirdrunframework);
$this->assertSame($firstrunframework, $thirdrunframework);
// Fetch another framework.
$fourthrunframework = $helper->get_framework_from_competency($comp2a);
$fourthrundbqueries = $DB->perf_get_queries();
$this->assertNotEquals($firstrundbqueries, $fourthrundbqueries);
$this->assertEquals($framework2, $fourthrunframework);
$this->assertNotSame($framework2, $fourthrunframework);
$fifthrunframework = $helper->get_framework_from_competency($comp2a);
$this->assertEquals($fourthrundbqueries, $DB->perf_get_queries());
$this->assertEquals($framework2, $fifthrunframework);
$this->assertSame($fourthrunframework, $fifthrunframework);
}
public function test_get_scale_from_competency(): void {
global $DB;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$scale1 = $dg->create_scale();
$scale2 = $dg->create_scale();
$cat1 = $dg->create_category();
$framework1 = $lpg->create_framework(['scaleid' => $scale1->id]);
$comp1 = $lpg->create_competency(['competencyframeworkid' => $framework1->get('id')]);
$comp2 = $lpg->create_competency(['competencyframeworkid' => $framework1->get('id'), 'scaleid' => $scale2->id]);
$comp3 = $lpg->create_competency(['competencyframeworkid' => $framework1->get('id')]);
$helper = new performance_helper();
$initdbqueries = $DB->perf_get_queries();
// Get the first scale.
$firstrunscale = $helper->get_scale_from_competency($comp1);
$firstrundbqueries = $DB->perf_get_queries();
$this->assertNotEquals($initdbqueries, $firstrundbqueries);
$this->assertEquals($scale1, $firstrunscale->get_record_data());
$secondrunscale = $helper->get_scale_from_competency($comp3);
$this->assertEquals($firstrundbqueries, $DB->perf_get_queries());
$this->assertSame($firstrunscale, $secondrunscale);
// Another scale, and its subsequent calls.
$thirdrunscale = $helper->get_scale_from_competency($comp2);
$thirddbqueries = $DB->perf_get_queries();
$this->assertNotEquals($firstrundbqueries, $thirddbqueries);
$this->assertEquals($scale2, $thirdrunscale->get_record_data());
$this->assertSame($thirdrunscale, $helper->get_scale_from_competency($comp2));
$this->assertEquals($thirddbqueries, $DB->perf_get_queries());
}
}
+562
View File
@@ -0,0 +1,562 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Plan persistent testcase.
*
* @package core_competency
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_test extends \advanced_testcase {
public function test_can_manage_user(): void {
$this->resetAfterTest(true);
$manage = create_role('Manage', 'manage', 'Plan manager');
$manageown = create_role('Manageown', 'manageown', 'Own plan manager');
$u1 = $this->getDataGenerator()->create_user();
$u2 = $this->getDataGenerator()->create_user();
$u3 = $this->getDataGenerator()->create_user();
$syscontext = \context_system::instance();
$u1context = \context_user::instance($u1->id);
$u2context = \context_user::instance($u2->id);
$u3context = \context_user::instance($u3->id);
assign_capability('moodle/competency:planmanage', CAP_ALLOW, $manage, $syscontext->id);
assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $manageown, $u2context->id);
role_assign($manage, $u1->id, $syscontext->id);
role_assign($manageown, $u2->id, $syscontext->id);
role_assign($manage, $u3->id, $u2context->id);
accesslib_clear_all_caches_for_unit_testing();
$this->setUser($u1);
$this->assertTrue(plan::can_manage_user($u1->id));
$this->assertTrue(plan::can_manage_user($u2->id));
$this->assertTrue(plan::can_manage_user($u3->id));
$this->setUser($u2);
$this->assertFalse(plan::can_manage_user($u1->id));
$this->assertTrue(plan::can_manage_user($u2->id));
$this->assertFalse(plan::can_manage_user($u3->id));
$this->setUser($u3);
$this->assertFalse(plan::can_manage_user($u1->id));
$this->assertTrue(plan::can_manage_user($u2->id));
$this->assertFalse(plan::can_manage_user($u3->id));
}
public function test_can_manage_user_draft(): void {
$this->resetAfterTest(true);
$manage = create_role('Manage', 'manage', 'Plan manager');
$manageown = create_role('Manageown', 'manageown', 'Own plan manager');
$managedraft = create_role('Managedraft', 'managedraft', 'Draft plan manager');
$manageowndraft = create_role('Manageowndraft', 'manageowndraft', 'Own draft plan manager');
$u1 = $this->getDataGenerator()->create_user();
$u2 = $this->getDataGenerator()->create_user();
$u3 = $this->getDataGenerator()->create_user();
$u4 = $this->getDataGenerator()->create_user();
$u5 = $this->getDataGenerator()->create_user();
$syscontext = \context_system::instance();
$u1context = \context_user::instance($u1->id);
$u2context = \context_user::instance($u2->id);
$u3context = \context_user::instance($u3->id);
$u4context = \context_user::instance($u4->id);
$u5context = \context_user::instance($u5->id);
assign_capability('moodle/competency:planmanage', CAP_ALLOW, $manage, $syscontext->id);
assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $manageown, $syscontext->id);
assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $managedraft, $syscontext->id);
assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $manageowndraft, $syscontext->id);
role_assign($manage, $u1->id, $syscontext->id);
role_assign($manageown, $u2->id, $syscontext->id);
role_assign($managedraft, $u3->id, $syscontext->id);
role_assign($managedraft, $u4->id, $u2context->id);
role_assign($manageowndraft, $u5->id, $syscontext->id);
accesslib_clear_all_caches_for_unit_testing();
$this->setUser($u1);
$this->assertFalse(plan::can_manage_user_draft($u1->id));
$this->assertFalse(plan::can_manage_user_draft($u2->id));
$this->assertFalse(plan::can_manage_user_draft($u3->id));
$this->assertFalse(plan::can_manage_user_draft($u4->id));
$this->assertFalse(plan::can_manage_user_draft($u5->id));
$this->setUser($u2);
$this->assertFalse(plan::can_manage_user_draft($u1->id));
$this->assertFalse(plan::can_manage_user_draft($u2->id));
$this->assertFalse(plan::can_manage_user_draft($u3->id));
$this->assertFalse(plan::can_manage_user_draft($u4->id));
$this->assertFalse(plan::can_manage_user_draft($u5->id));
$this->setUser($u3);
$this->assertTrue(plan::can_manage_user_draft($u1->id));
$this->assertTrue(plan::can_manage_user_draft($u2->id));
$this->assertTrue(plan::can_manage_user_draft($u3->id));
$this->assertTrue(plan::can_manage_user_draft($u4->id));
$this->assertTrue(plan::can_manage_user_draft($u5->id));
$this->setUser($u4);
$this->assertFalse(plan::can_manage_user_draft($u1->id));
$this->assertTrue(plan::can_manage_user_draft($u2->id));
$this->assertFalse(plan::can_manage_user_draft($u3->id));
$this->assertFalse(plan::can_manage_user_draft($u4->id));
$this->assertFalse(plan::can_manage_user_draft($u5->id));
$this->setUser($u5);
$this->assertFalse(plan::can_manage_user_draft($u1->id));
$this->assertFalse(plan::can_manage_user_draft($u2->id));
$this->assertFalse(plan::can_manage_user_draft($u3->id));
$this->assertFalse(plan::can_manage_user_draft($u4->id));
$this->assertTrue(plan::can_manage_user_draft($u5->id));
}
public function test_can_read_user(): void {
$this->resetAfterTest(true);
$read = create_role('Read', 'read', 'Plan reader');
$readown = create_role('Readown', 'readown', 'Own plan reader');
$u1 = $this->getDataGenerator()->create_user();
$u2 = $this->getDataGenerator()->create_user();
$u3 = $this->getDataGenerator()->create_user();
$syscontext = \context_system::instance();
$u1context = \context_user::instance($u1->id);
$u2context = \context_user::instance($u2->id);
$u3context = \context_user::instance($u3->id);
assign_capability('moodle/competency:planview', CAP_ALLOW, $read, $syscontext->id);
assign_capability('moodle/competency:planviewown', CAP_ALLOW, $readown, $u2context->id);
role_assign($read, $u1->id, $syscontext->id);
role_assign($readown, $u2->id, $syscontext->id);
role_assign($read, $u3->id, $u2context->id);
accesslib_clear_all_caches_for_unit_testing();
$this->setUser($u1);
$this->assertTrue(plan::can_read_user($u1->id));
$this->assertTrue(plan::can_read_user($u2->id));
$this->assertTrue(plan::can_read_user($u3->id));
$this->setUser($u2);
$this->assertFalse(plan::can_read_user($u1->id));
$this->assertTrue(plan::can_read_user($u2->id));
$this->assertFalse(plan::can_read_user($u3->id));
$this->setUser($u3);
$this->assertFalse(plan::can_read_user($u1->id));
$this->assertTrue(plan::can_read_user($u2->id));
$this->assertTrue(plan::can_read_user($u3->id)); // Due to the default capability.
}
public function test_can_read_user_draft(): void {
$this->resetAfterTest(true);
$read = create_role('Read', 'read', 'Plan readr');
$readown = create_role('Readown', 'readown', 'Own plan readr');
$readdraft = create_role('Readdraft', 'readdraft', 'Draft plan readr');
$readowndraft = create_role('Readowndraft', 'readowndraft', 'Own draft plan readr');
$u1 = $this->getDataGenerator()->create_user();
$u2 = $this->getDataGenerator()->create_user();
$u3 = $this->getDataGenerator()->create_user();
$u4 = $this->getDataGenerator()->create_user();
$u5 = $this->getDataGenerator()->create_user();
$syscontext = \context_system::instance();
$u1context = \context_user::instance($u1->id);
$u2context = \context_user::instance($u2->id);
$u3context = \context_user::instance($u3->id);
$u4context = \context_user::instance($u4->id);
$u5context = \context_user::instance($u5->id);
assign_capability('moodle/competency:planview', CAP_ALLOW, $read, $syscontext->id);
assign_capability('moodle/competency:planviewown', CAP_ALLOW, $readown, $syscontext->id);
assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $readdraft, $syscontext->id);
assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $readowndraft, $syscontext->id);
assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $readowndraft, $syscontext->id);
role_assign($read, $u1->id, $syscontext->id);
role_assign($readown, $u2->id, $syscontext->id);
role_assign($readdraft, $u3->id, $syscontext->id);
role_assign($readdraft, $u4->id, $u2context->id);
role_assign($readowndraft, $u5->id, $syscontext->id);
accesslib_clear_all_caches_for_unit_testing();
$this->setUser($u1);
$this->assertFalse(plan::can_read_user_draft($u1->id));
$this->assertFalse(plan::can_read_user_draft($u2->id));
$this->assertFalse(plan::can_read_user_draft($u3->id));
$this->assertFalse(plan::can_read_user_draft($u4->id));
$this->assertFalse(plan::can_read_user_draft($u5->id));
$this->setUser($u2);
$this->assertFalse(plan::can_read_user_draft($u1->id));
$this->assertFalse(plan::can_read_user_draft($u2->id));
$this->assertFalse(plan::can_read_user_draft($u3->id));
$this->assertFalse(plan::can_read_user_draft($u4->id));
$this->assertFalse(plan::can_read_user_draft($u5->id));
$this->setUser($u3);
$this->assertTrue(plan::can_read_user_draft($u1->id));
$this->assertTrue(plan::can_read_user_draft($u2->id));
$this->assertTrue(plan::can_read_user_draft($u3->id));
$this->assertTrue(plan::can_read_user_draft($u4->id));
$this->assertTrue(plan::can_read_user_draft($u5->id));
$this->setUser($u4);
$this->assertFalse(plan::can_read_user_draft($u1->id));
$this->assertTrue(plan::can_read_user_draft($u2->id));
$this->assertFalse(plan::can_read_user_draft($u3->id));
$this->assertFalse(plan::can_read_user_draft($u4->id));
$this->assertFalse(plan::can_read_user_draft($u5->id));
$this->setUser($u5);
$this->assertFalse(plan::can_read_user_draft($u1->id));
$this->assertFalse(plan::can_read_user_draft($u2->id));
$this->assertFalse(plan::can_read_user_draft($u3->id));
$this->assertFalse(plan::can_read_user_draft($u4->id));
$this->assertTrue(plan::can_read_user_draft($u5->id));
}
public function test_validate_duedate(): void {
global $DB;
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
$user = $dg->create_user();
$record = array('userid' => $user->id,
'status' => plan::STATUS_DRAFT,
'duedate' => time() - 8000);
// Ignore duedate validation on create/update draft plan.
$plan = $lpg->create_plan($record);
$this->assertInstanceOf(plan::class, $plan);
// Passing from draft to active.
$plan->set('status', plan::STATUS_ACTIVE);
// Draft to active with duedate in the past.
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedateinthepast', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Draft to active: past date => past date(fail).
$plan->set('duedate', time() - 100);
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedateinthepast', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Draft to active: past date => too soon (fail).
$plan->set('duedate', time() + 100);
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedatetoosoon', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Draft to active: past date => future date (pass).
$plan->set('duedate', time() + plan::DUEDATE_THRESHOLD + 10);
$this->assertEquals(true, $plan->validate());
// Draft to active: past date => unset date (pass).
$plan->set('duedate', 0);
$this->assertEquals(true, $plan->validate());
// Updating active plan.
$plan->update();
// Active to active: past => same past (pass).
$record = $plan->to_record();
$record->duedate = 1;
$DB->update_record(plan::TABLE, $record);
$plan->read();
$plan->set('description', uniqid()); // Force revalidation.
$this->assertTrue($plan->is_valid());
// Active to active: past => unset (pass).
$plan->set('duedate', 0);
$this->assertTrue($plan->is_valid());
$plan->update();
// Active to active: unset => unset (pass).
$plan->set('description', uniqid()); // Force revalidation.
$this->assertTrue($plan->is_valid());
// Active to active: unset date => past date(fail).
$plan->set('duedate', time() - 100);
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedateinthepast', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Active to active: unset date => too soon (fail).
$plan->set('duedate', time() + 100);
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedatetoosoon', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Active to active: unset date => future date (pass).
$plan->set('duedate', time() + plan::DUEDATE_THRESHOLD + 10);
$this->assertEquals(true, $plan->validate());
// Updating active plan with future date.
$plan->update();
// Active to active: future => same future (pass).
$plan->set('description', uniqid()); // Force revalidation.
$this->assertTrue($plan->is_valid());
// Active to active: future date => unset date (pass).
$plan->set('duedate', 0);
$this->assertEquals(true, $plan->validate());
// Active to active: future date => past date(fail).
$plan->set('duedate', time() - 100);
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedateinthepast', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Active to active: future date => too soon (fail).
$plan->set('duedate', time() + 100);
$expected = array(
'duedate' => new \lang_string('errorcannotsetduedatetoosoon', 'core_competency'),
);
$this->assertEquals($expected, $plan->validate());
// Active to active: future date => future date (pass).
$plan->set('duedate', time() + plan::DUEDATE_THRESHOLD + 10);
$this->assertEquals(true, $plan->validate());
// Completing plan: with due date in the past.
$record = $plan->to_record();
$record->status = plan::STATUS_ACTIVE;
$record->duedate = time() - 200;
$DB->update_record(plan::TABLE, $record);
$success = api::complete_plan($plan->get('id'));
$this->assertTrue($success);
// Completing plan: with due date too soon (pass).
$record = $plan->to_record();
$record->status = plan::STATUS_ACTIVE;
$record->duedate = time() + 200;
$DB->update_record(plan::TABLE, $record);
$success = api::complete_plan($plan->get('id'));
$this->assertTrue($success);
// Completing plan: with due date in the future (pass).
$record = $plan->to_record();
$record->status = plan::STATUS_ACTIVE;
$record->duedate = time() + plan::DUEDATE_THRESHOLD + 10;
$DB->update_record(plan::TABLE, $record);
$success = api::complete_plan($plan->get('id'));
$this->assertTrue($success);
// Completing plan: with due date unset (pass).
$record = $plan->to_record();
$record->status = plan::STATUS_ACTIVE;
$record->duedate = 0;
$DB->update_record(plan::TABLE, $record);
$success = api::complete_plan($plan->get('id'));
$this->assertTrue($success);
// Reopening plan: with due date in the past => duedate unset.
$record = $plan->to_record();
$record->status = plan::STATUS_COMPLETE;
$record->duedate = time() - 200;
$DB->update_record(plan::TABLE, $record);
$success = api::reopen_plan($plan->get('id'));
$this->assertTrue($success);
$plan->read();
$this->assertEquals(0, $plan->get('duedate'));
// Reopening plan: with due date too soon => duedate unset.
$record = $plan->to_record();
$record->status = plan::STATUS_COMPLETE;
$record->duedate = time() + 100;
$DB->update_record(plan::TABLE, $record);
$success = api::reopen_plan($plan->get('id'));
$this->assertTrue($success);
$plan->read();
$this->assertEquals(0, $plan->get('duedate'));
// Reopening plan: with due date in the future => duedate unchanged.
$record = $plan->to_record();
$record->status = plan::STATUS_COMPLETE;
$duedate = time() + plan::DUEDATE_THRESHOLD + 10;
$record->duedate = $duedate;
$DB->update_record(plan::TABLE, $record);
$success = api::reopen_plan($plan->get('id'));
$this->assertTrue($success);
$plan->read();
// Check that the due date has not changed.
$this->assertNotEquals(0, $plan->get('duedate'));
$this->assertEquals($duedate, $plan->get('duedate'));
}
public function test_get_by_user_and_competency(): void {
$this->resetAfterTest();
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$tpl1 = $lpg->create_template();
$lpg->create_template_competency(array('competencyid' => $c1->get('id'), 'templateid' => $tpl1->get('id')));
$p1 = $lpg->create_plan(array('userid' => $u1->id));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c1->get('id')));
$p2 = $lpg->create_plan(array('userid' => $u2->id));
$lpg->create_plan_competency(array('planid' => $p2->get('id'), 'competencyid' => $c1->get('id')));
$p3 = $lpg->create_plan(array('userid' => $u3->id, 'templateid' => $tpl1->get('id')));
$p4 = $lpg->create_plan(array('userid' => $u4->id, 'templateid' => $tpl1->get('id')));
api::complete_plan($p2);
api::complete_plan($p4);
// Finding a plan, not completed.
$plans = plan::get_by_user_and_competency($u1->id, $c1->get('id'));
$this->assertCount(1, $plans);
$plan = array_shift($plans);
$this->assertEquals($p1->get('id'), $plan->get('id'));
$this->assertNotEquals(plan::STATUS_COMPLETE, $plan->get('status'));
// Finding a completed plan.
$plans = plan::get_by_user_and_competency($u2->id, $c1->get('id'));
$this->assertCount(1, $plans);
$plan = array_shift($plans);
$this->assertEquals($p2->get('id'), $plan->get('id'));
$this->assertEquals(plan::STATUS_COMPLETE, $plan->get('status'));
// Finding a plan based on a template, not completed.
$plans = plan::get_by_user_and_competency($u3->id, $c1->get('id'));
$this->assertCount(1, $plans);
$plan = array_shift($plans);
$this->assertEquals($p3->get('id'), $plan->get('id'));
$this->assertTrue($plan->is_based_on_template());
$this->assertNotEquals(plan::STATUS_COMPLETE, $plan->get('status'));
// Finding a plan based on a template.
$plans = plan::get_by_user_and_competency($u4->id, $c1->get('id'));
$this->assertCount(1, $plans);
$plan = array_shift($plans);
$this->assertEquals($p4->get('id'), $plan->get('id'));
$this->assertTrue($plan->is_based_on_template());
$this->assertEquals(plan::STATUS_COMPLETE, $plan->get('status'));
// Finding more than one plan, no template.
$p5 = $lpg->create_plan(array('userid' => $u1->id));
$lpg->create_plan_competency(array('planid' => $p5->get('id'), 'competencyid' => $c1->get('id')));
$plans = plan::get_by_user_and_competency($u1->id, $c1->get('id'));
$this->assertCount(2, $plans);
$plan = array_shift($plans);
$this->assertEquals($p1->get('id'), $plan->get('id'));
$plan = array_shift($plans);
$this->assertEquals($p5->get('id'), $plan->get('id'));
// Finding more than one plan, with template.
$p6 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get('id')));
$plans = plan::get_by_user_and_competency($u1->id, $c1->get('id'));
$this->assertCount(3, $plans);
$plan = array_shift($plans);
$this->assertEquals($p1->get('id'), $plan->get('id'));
$plan = array_shift($plans);
$this->assertEquals($p5->get('id'), $plan->get('id'));
$plan = array_shift($plans);
$this->assertEquals($p6->get('id'), $plan->get('id'));
// Finding no plans.
$plans = plan::get_by_user_and_competency($u1->id, $c2->get('id'));
$this->assertCount(0, $plans);
}
public function test_get_competency(): void {
$this->resetAfterTest();
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$tpl1 = $lpg->create_template();
$p1 = $lpg->create_plan(array('userid' => $u1->id));
$p2 = $lpg->create_plan(array('userid' => $u2->id));
$p3 = $lpg->create_plan(array('userid' => $u3->id, 'templateid' => $tpl1->get('id')));
$p4 = $lpg->create_plan(array('userid' => $u4->id, 'templateid' => $tpl1->get('id')));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c1->get('id')));
$lpg->create_plan_competency(array('planid' => $p2->get('id'), 'competencyid' => $c2->get('id')));
$lpg->create_template_competency(array('templateid' => $tpl1->get('id'), 'competencyid' => $c3->get('id')));
$lpg->create_template_competency(array('templateid' => $tpl1->get('id'), 'competencyid' => $c4->get('id')));
// Completing the plans and removing a competency from the template.
api::complete_plan($p2);
api::complete_plan($p4);
api::remove_competency_from_template($tpl1->get('id'), $c4->get('id'));
// We can find all competencies.
$this->assertEquals($c1->to_record(), $p1->get_competency($c1->get('id'))->to_record());
$this->assertEquals($c2->to_record(), $p2->get_competency($c2->get('id'))->to_record());
$this->assertEquals($c3->to_record(), $p3->get_competency($c3->get('id'))->to_record());
$this->assertEquals($c4->to_record(), $p4->get_competency($c4->get('id'))->to_record());
// Getting the competency 4 from the non-completed plan based on a template p4, will throw an exception.
$this->expectException('coding_exception');
$this->expectExceptionMessage('The competency does not belong to this template:');
$p3->get_competency($c4->get('id'));
}
}
File diff suppressed because it is too large Load Diff
+307
View File
@@ -0,0 +1,307 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency\task;
use core_competency\api;
use core_competency\plan;
use core_competency\template;
/**
* Task tests.
*
* @package core_competency
* @copyright 2015 Issam Taboubi <issam.taboubi@umontreal.ca>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_test extends \advanced_testcase {
public function test_sync_plans_from_cohorts_task(): void {
global $DB;
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
// Sql to simulate the execution in time.
$cmsql = "UPDATE {cohort_members} SET timeadded = :currenttime WHERE cohortid = :cohortid AND userid = :userid";
$tplsql = "UPDATE {" . template::TABLE . "} SET timemodified = :currenttime WHERE id = :templateid";
$plansql = "UPDATE {" . plan::TABLE . "} SET timemodified = :currenttime WHERE id = :planid";
$currenttime = time();
$user1 = $dg->create_user();
$user2 = $dg->create_user();
$user3 = $dg->create_user();
$user4 = $dg->create_user();
$user5 = $dg->create_user();
$cohort = $dg->create_cohort();
$tpl = $lpg->create_template();
// Add 2 users to the cohort.
cohort_add_member($cohort->id, $user1->id);
cohort_add_member($cohort->id, $user2->id);
// Creating plans from template cohort.
$templatecohort = api::create_template_cohort($tpl->get('id'), $cohort->id);
$created = api::create_plans_from_template_cohort($tpl->get('id'), $cohort->id);
$this->assertEquals(2, $created);
$task = \core\task\manager::get_scheduled_task('\\core\\task\\sync_plans_from_template_cohorts_task');
$this->assertInstanceOf('\core\task\sync_plans_from_template_cohorts_task', $task);
// Add two more users to the cohort.
cohort_add_member($cohort->id, $user3->id);
cohort_add_member($cohort->id, $user4->id);
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Test if remove user from cohort will affect plans.
cohort_remove_member($cohort->id, $user3->id);
cohort_remove_member($cohort->id, $user4->id);
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// The template is now hidden, and I've added a user with a missing plan. Nothing should happen.
$currenttime = $currenttime + 1;
$tpl->set('visible', false);
$tpl->update();
$DB->execute($tplsql, array('currenttime' => $currenttime, 'templateid' => $tpl->get('id')));
$currenttime = $currenttime + 1;
cohort_add_member($cohort->id, $user5->id);
$DB->execute($cmsql, array('currenttime' => $currenttime, 'cohortid' => $cohort->id, 'userid' => $user5->id));
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Now I set the template as visible again, the plan is created.
$currenttime = $currenttime + 1;
$tpl->set('visible', true);
$tpl->update();
$DB->execute($tplsql, array('currenttime' => $currenttime, 'templateid' => $tpl->get('id')));
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertTrue(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(5, plan::count_records(array('templateid' => $tpl->get('id'))));
// Let's unlink the plan and run the task again, it should not be recreated.
$currenttime = $currenttime + 1;
$plan = plan::get_record(array('userid' => $user5->id, 'templateid' => $tpl->get('id')));
api::unlink_plan_from_template($plan);
$DB->execute($plansql, array('currenttime' => $currenttime, 'planid' => $plan->get('id')));
$this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Adding users to cohort that already exist in plans.
$currenttime = $currenttime + 1;
cohort_add_member($cohort->id, $user3->id);
cohort_add_member($cohort->id, $user4->id);
$DB->execute($cmsql, array('currenttime' => $currenttime, 'cohortid' => $cohort->id, 'userid' => $user3->id));
$DB->execute($cmsql, array('currenttime' => $currenttime, 'cohortid' => $cohort->id, 'userid' => $user3->id));
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Test a user plan deleted will not be recreated.
$currenttime = $currenttime + 1;
$plan = plan::get_record(array('userid' => $user4->id, 'templateid' => $tpl->get('id')));
api::delete_plan($plan->get('id'));
$currenttime = $currenttime + 1;
$task->execute();
$task->set_last_run_time($currenttime);
$this->assertEquals(3, plan::count_records(array('templateid' => $tpl->get('id'))));
}
public function test_sync_plans_from_cohorts_with_templateduedate_task(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$user1 = $dg->create_user();
$user2 = $dg->create_user();
$user3 = $dg->create_user();
$user4 = $dg->create_user();
$user5 = $dg->create_user();
$cohort = $dg->create_cohort();
$tpl = $lpg->create_template(array('duedate' => time() + 400));
// Add 2 users to the cohort.
cohort_add_member($cohort->id, $user1->id);
cohort_add_member($cohort->id, $user2->id);
// Creating plans from template cohort.
$templatecohort = api::create_template_cohort($tpl->get('id'), $cohort->id);
$created = api::create_plans_from_template_cohort($tpl->get('id'), $cohort->id);
$this->assertEquals(2, $created);
$task = \core\task\manager::get_scheduled_task('\\core\\task\\sync_plans_from_template_cohorts_task');
$this->assertInstanceOf('\core\task\sync_plans_from_template_cohorts_task', $task);
// Add two more users to the cohort.
cohort_add_member($cohort->id, $user3->id);
cohort_add_member($cohort->id, $user4->id);
$task->execute();
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Test if remove user from cohort will affect plans.
cohort_remove_member($cohort->id, $user3->id);
cohort_remove_member($cohort->id, $user4->id);
$task->execute();
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// The template is now hidden, and I've added a user with a missing plan. Nothing should happen.
$tpl->set('visible', false);
$tpl->update();
cohort_add_member($cohort->id, $user5->id);
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
$task->execute();
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Now I set the template as visible again, the plan is created.
$tpl->set('visible', true);
$tpl->update();
$task->execute();
$this->assertTrue(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(5, plan::count_records(array('templateid' => $tpl->get('id'))));
// Let's unlink the plan and run the task again, it should not be recreated.
$plan = plan::get_record(array('userid' => $user5->id, 'templateid' => $tpl->get('id')));
api::unlink_plan_from_template($plan);
$this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
$task->execute();
$this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
$this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
// Adding users to cohort that already exist in plans.
cohort_add_member($cohort->id, $user3->id);
cohort_add_member($cohort->id, $user4->id);
$task->execute();
$this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
}
public function test_sync_plans_from_cohorts_with_passed_duedate(): void {
global $DB;
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$user1 = $dg->create_user();
$user2 = $dg->create_user();
$cohort = $dg->create_cohort();
$tpl = $lpg->create_template(array('duedate' => time() + 1000));
$templatecohort = api::create_template_cohort($tpl->get('id'), $cohort->id);
$task = \core\task\manager::get_scheduled_task('\\core\\task\\sync_plans_from_template_cohorts_task');
// Add 1 user to the cohort.
cohort_add_member($cohort->id, $user1->id);
// Creating plans from template cohort.
$task->execute();
$this->assertEquals(1, plan::count_records());
// Now add another user, but this time the template will be expired.
cohort_add_member($cohort->id, $user2->id);
$record = $tpl->to_record();
$record->duedate = time() - 10000;
$DB->update_record(template::TABLE, $record);
$tpl->read();
$task->execute();
$this->assertEquals(1, plan::count_records()); // Still only one plan.
// Pretend it wasn't expired.
$tpl->set('duedate', time() + 100);
$tpl->update();
$task->execute();
$this->assertEquals(2, plan::count_records()); // Now there is two.
}
public function test_complete_plans_task(): void {
global $DB;
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$user = $dg->create_user();
$up1 = $lpg->create_plan(array('userid' => $user->id,
'status' => plan::STATUS_DRAFT));
$up2 = $lpg->create_plan(array('userid' => $user->id,
'status' => plan::STATUS_ACTIVE));
// Set duedate in the past.
$date = new \DateTime('yesterday');
$record1 = $up1->to_record();
$record2 = $up2->to_record();
$record1->duedate = $date->getTimestamp();
$record2->duedate = $date->getTimestamp();
$DB->update_record(plan::TABLE, $record1);
$DB->update_record(plan::TABLE, $record2);
$task = \core\task\manager::get_scheduled_task('\\core\\task\\complete_plans_task');
$this->assertInstanceOf('\\core\\task\\complete_plans_task', $task);
// Test that draft plan can not be completed on running task.
$task->execute();
$plandraft = api::read_plan($up1->get('id'));
$this->assertEquals(plan::STATUS_DRAFT, $plandraft->get('status'));
// Test that active plan can be completed on running task.
$task->execute();
$planactive = api::read_plan($up2->get('id'));
$this->assertEquals(plan::STATUS_COMPLETE, $planactive->get('status'));
}
}
+104
View File
@@ -0,0 +1,104 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* Template persistent 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 template_test extends \advanced_testcase {
public function test_validate_duedate(): void {
global $DB;
$this->resetAfterTest();
$tpl = $this->getDataGenerator()->get_plugin_generator('core_competency')->create_template();
// No due date -> pass.
$tpl->set('duedate', 0);
$this->assertTrue($tpl->is_valid());
// Setting new due date in the past -> fail.
$tpl->set('duedate', 1);
$errors = $tpl->get_errors();
$this->assertCount(1, $errors);
$this->assertArrayHasKey('duedate', $errors);
// Setting new due date in very close past -> pass.
$tpl->set('duedate', time() - 10);
$this->assertTrue($tpl->is_valid());
// Setting new due date in future -> pass.
$tpl->set('duedate', time() + 600);
$this->assertTrue($tpl->is_valid());
// Save due date in the future.
$tpl->update();
// Going from future date to past -> fail.
$tpl->set('duedate', 1);
$errors = $tpl->get_errors();
$this->assertCount(1, $errors);
$this->assertArrayHasKey('duedate', $errors);
// Going from future date to none -> pass.
$tpl->set('duedate', 0);
$this->assertTrue($tpl->is_valid());
// Going from future date to other future -> pass.
$tpl->set('duedate', time() + 6000);
$this->assertTrue($tpl->is_valid());
// Going from future date to close past -> pass.
$tpl->set('duedate', time() - 10);
$this->assertTrue($tpl->is_valid());
// Mocking past due date.
$record = $tpl->to_record();
$record->duedate = 1;
$DB->update_record(template::TABLE, $record);
$tpl->read();
$this->assertEquals(1, $tpl->get('duedate'));
// Not changing the past due date -> pass.
// Note: changing visibility to force validation.
$tpl->set('visible', 0);
$tpl->set('visible', 1);
$this->assertTrue($tpl->is_valid());
// Changing past due date to other past -> fail.
$tpl->set('duedate', 10);
$errors = $tpl->get_errors();
$this->assertCount(1, $errors);
$this->assertArrayHasKey('duedate', $errors);
// Changing past due date close past -> pass.
$tpl->set('duedate', time() + 10);
$this->assertTrue($tpl->is_valid());
// Changing past due date to future -> pass.
$tpl->set('duedate', time() + 1000);
$this->assertTrue($tpl->is_valid());
// Changing past due date to none -> pass.
$tpl->set('duedate', 0);
$this->assertTrue($tpl->is_valid());
}
}
@@ -0,0 +1,81 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_competency;
/**
* User evidence competency persistent testcase.
*
* @package core_competency
* @copyright 2016 Serge Gauthier - <serge.gauthier.2@umontreal.ca>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_evidence_competency_test extends \advanced_testcase {
public function test_get_user_competencies_by_userevidenceid(): void {
global $CFG, $DB;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$u1 = $dg->create_user();
// Create framework with competencies.
$fw = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $fw->get('id')));
$c2 = $lpg->create_competency(array('competencyframeworkid' => $fw->get('id')));
$c3 = $lpg->create_competency(array('competencyframeworkid' => $fw->get('id')));
$c4 = $lpg->create_competency(array('competencyframeworkid' => $fw->get('id')));
// Create a plan with competencies.
$p1 = $lpg->create_plan(array('userid' => $u1->id));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c1->get('id')));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c2->get('id')));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c3->get('id')));
$lpg->create_plan_competency(array('planid' => $p1->get('id'), 'competencyid' => $c4->get('id')));
// Create a prior learning evidence and link competencies.
$ue1 = $lpg->create_user_evidence(array('userid' => $u1->id));
$uec11 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue1->get('id'), 'competencyid' => $c1->get('id')));
$uec12 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue1->get('id'), 'competencyid' => $c2->get('id')));
$uec13 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue1->get('id'), 'competencyid' => $c3->get('id')));
$uc11 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c1->get('id')));
$uc12 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c2->get('id')));
$uc13 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get('id')));
// Create an other prior learning evidence and link competencies.
$ue2 = $lpg->create_user_evidence(array('userid' => $u1->id));
$uec22 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue2->get('id'), 'competencyid' => $c4->get('id')));
$uc22 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c4->get('id')));
// Check the user competencies associated to the first prior learning evidence.
$ucs = user_evidence_competency::get_user_competencies_by_userevidenceid($ue1->get('id'));
$this->assertCount(3, $ucs);
$uc = array_shift($ucs);
$this->assertEquals($uc->get('id'), $uc11->get('id'));
$uc = array_shift($ucs);
$this->assertEquals($uc->get('id'), $uc12->get('id'));
$uc = array_shift($ucs);
$this->assertEquals($uc->get('id'), $uc13->get('id'));
// Check the user competencies associated to the second prior learning evidence.
$ucs = user_evidence_competency::get_user_competencies_by_userevidenceid($ue2->get('id'));
$this->assertCount(1, $ucs);
$uc = array_shift($ucs);
$this->assertEquals($uc->get('id'), $uc22->get('id'));
}
}