| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 | // This file is part of Moodle - http://moodle.org/
 | 
        
           |  |  | 3 | //
 | 
        
           |  |  | 4 | // Moodle is free software: you can redistribute it and/or modify
 | 
        
           |  |  | 5 | // it under the terms of the GNU General Public License as published by
 | 
        
           |  |  | 6 | // the Free Software Foundation, either version 3 of the License, or
 | 
        
           |  |  | 7 | // (at your option) any later version.
 | 
        
           |  |  | 8 | //
 | 
        
           |  |  | 9 | // Moodle is distributed in the hope that it will be useful,
 | 
        
           |  |  | 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
        
           |  |  | 12 | // GNU General Public License for more details.
 | 
        
           |  |  | 13 | //
 | 
        
           |  |  | 14 | // You should have received a copy of the GNU General Public License
 | 
        
           |  |  | 15 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | namespace core_competency;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | /**
 | 
        
           |  |  | 20 |  * Competency ruleoutcome override grade tests
 | 
        
           |  |  | 21 |  *
 | 
        
           |  |  | 22 |  * @package    core_competency
 | 
        
           |  |  | 23 |  * @copyright  2022 Matthew Hilton <matthewhilton@catalyst-au.net>
 | 
        
           |  |  | 24 |  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 25 |  */
 | 
        
           | 1441 | ariadna | 26 | final class competency_override_test extends \advanced_testcase {
 | 
        
           | 1 | efrain | 27 |   | 
        
           |  |  | 28 |     /** @var \stdClass course record. */
 | 
        
           |  |  | 29 |     protected $course;
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 |     /** @var \stdClass user record. */
 | 
        
           |  |  | 32 |     protected $user;
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 |     /** @var \stdClass block instance record. */
 | 
        
           |  |  | 35 |     protected $scale;
 | 
        
           |  |  | 36 |   | 
        
           |  |  | 37 |     /** @var competency_framework loading competency frameworks from the DB. */
 | 
        
           |  |  | 38 |     protected $framework;
 | 
        
           |  |  | 39 |   | 
        
           |  |  | 40 |     /** @var plan loading competency plans from the DB. */
 | 
        
           |  |  | 41 |     protected $plan;
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 |     /** @var competency loading competency from the DB. */
 | 
        
           |  |  | 44 |     protected $comp1;
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 |     /** @var competency loading competency from the DB. */
 | 
        
           |  |  | 47 |     protected $comp2;
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 |     /** @var \stdClass course module. */
 | 
        
           |  |  | 50 |     protected $cm;
 | 
        
           |  |  | 51 |   | 
        
           |  |  | 52 |     /** @var \completion_info completion information. */
 | 
        
           |  |  | 53 |     protected $completion;
 | 
        
           |  |  | 54 |   | 
        
           |  |  | 55 |     /** @var \context_course context course. */
 | 
        
           |  |  | 56 |     protected $context;
 | 
        
           |  |  | 57 |   | 
        
           |  |  | 58 |     public function setUp(): void {
 | 
        
           | 1441 | ariadna | 59 |         parent::setUp();
 | 
        
           | 1 | efrain | 60 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 61 |         $this->setAdminUser();
 | 
        
           |  |  | 62 |         $dg = $this->getDataGenerator();
 | 
        
           |  |  | 63 |         $lpg = $dg->get_plugin_generator('core_competency');
 | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |         // Create user in course.
 | 
        
           |  |  | 66 |         $c1 = $dg->create_course((object) ['enablecompletion' => true]);
 | 
        
           |  |  | 67 |         $u1 = $dg->create_user();
 | 
        
           |  |  | 68 |         $dg->enrol_user($u1->id, $c1->id);
 | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 |         // Create framework with three values.
 | 
        
           |  |  | 71 |         $scale = $dg->create_scale(["scale" => "not,partially,fully"]);
 | 
        
           |  |  | 72 |         $scaleconfiguration = json_encode([
 | 
        
           |  |  | 73 |             ['scaleid' => $scale->id],
 | 
        
           |  |  | 74 |             ['id' => 1, 'scaledefault' => 1, 'proficient' => 1]
 | 
        
           |  |  | 75 |         ]);
 | 
        
           |  |  | 76 |         $framework = $lpg->create_framework([
 | 
        
           |  |  | 77 |             'scaleid' => $scale->id,
 | 
        
           |  |  | 78 |             'scaleconfiguration' => $scaleconfiguration
 | 
        
           |  |  | 79 |         ]);
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 |         $plan = $lpg->create_plan(['userid' => $u1->id]);
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 |         $comp1 = $lpg->create_competency([
 | 
        
           |  |  | 84 |             'competencyframeworkid' => $framework->get('id'),
 | 
        
           |  |  | 85 |             'scaleid' => $scale->id,
 | 
        
           |  |  | 86 |             'scaleconfiguration' => $scaleconfiguration
 | 
        
           |  |  | 87 |         ]);
 | 
        
           |  |  | 88 |   | 
        
           |  |  | 89 |         $comp2 = $lpg->create_competency([
 | 
        
           |  |  | 90 |             'competencyframeworkid' => $framework->get('id'),
 | 
        
           |  |  | 91 |             'scaleid' => $scale->id,
 | 
        
           |  |  | 92 |             'scaleconfiguration' => $scaleconfiguration
 | 
        
           |  |  | 93 |         ]);
 | 
        
           |  |  | 94 |   | 
        
           |  |  | 95 |         api::add_competency_to_plan($plan->get('id'), $comp1->get('id'));
 | 
        
           |  |  | 96 |         api::add_competency_to_plan($plan->get('id'), $comp2->get('id'));
 | 
        
           |  |  | 97 |   | 
        
           |  |  | 98 |         $lpg->create_course_competency([
 | 
        
           |  |  | 99 |             'courseid' => $c1->id,
 | 
        
           |  |  | 100 |             'competencyid' => $comp1->get('id'),
 | 
        
           |  |  | 101 |             'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE,
 | 
        
           |  |  | 102 |         ]);
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 |         $lpg->create_course_competency([
 | 
        
           |  |  | 105 |             'courseid' => $c1->id,
 | 
        
           |  |  | 106 |             'competencyid' => $comp2->get('id'),
 | 
        
           |  |  | 107 |             'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE,
 | 
        
           |  |  | 108 |         ]);
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 |         $label = $dg->create_module('label', ['course' => $c1, 'completion' => COMPLETION_VIEWED, 'completionview' => 1]);
 | 
        
           |  |  | 111 |         $cm = get_coursemodule_from_instance('label', $label->id);
 | 
        
           |  |  | 112 |         $completion = new \completion_info($c1);
 | 
        
           |  |  | 113 |         $this->assertEquals(COMPLETION_ENABLED, $completion->is_enabled($cm));
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 |         // Link course module with the competency and setup a rule to complete the competency when the module is completed.
 | 
        
           |  |  | 116 |         api::add_competency_to_course_module($cm, $comp1->get('id'));
 | 
        
           |  |  | 117 |         api::add_competency_to_course_module($cm, $comp2->get('id'));
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 |         $coursemodulecomps = api::list_course_module_competencies_in_course_module($cm);
 | 
        
           |  |  | 120 |         $this->assertCount(2, $coursemodulecomps);
 | 
        
           |  |  | 121 |         api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE);
 | 
        
           |  |  | 122 |         api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE);
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 |         $this->course = $c1;
 | 
        
           |  |  | 125 |         $this->user = $u1;
 | 
        
           |  |  | 126 |         $this->scale = $scale;
 | 
        
           |  |  | 127 |         $this->framework = $framework;
 | 
        
           |  |  | 128 |         $this->plan = $plan;
 | 
        
           |  |  | 129 |         $this->comp1 = $comp1;
 | 
        
           |  |  | 130 |         $this->comp2 = $comp2;
 | 
        
           |  |  | 131 |         $this->cm = $cm;
 | 
        
           |  |  | 132 |         $this->completion = new \completion_info($c1);
 | 
        
           |  |  | 133 |         $this->context = \context_course::instance($this->course->id);
 | 
        
           |  |  | 134 |     }
 | 
        
           |  |  | 135 |   | 
        
           |  |  | 136 |     /**
 | 
        
           |  |  | 137 |      * Test ruleoutcome overridegrade is correctly applied when coursemodule completion is processed.
 | 
        
           |  |  | 138 |      *
 | 
        
           |  |  | 139 |      * @covers \core_competency\api::set_course_module_competency_ruleoutcome
 | 
        
           |  |  | 140 |      */
 | 
        
           |  |  | 141 |     public function test_ruleoutcome_overridegrade(): void {
 | 
        
           |  |  | 142 |         // Initially the competency (and hence all the child competencies) should not be complete for the user.
 | 
        
           |  |  | 143 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 144 |         $this->assertEquals(0, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 145 |         $this->assertEquals(0, $usercomp->get('grade'));
 | 
        
           |  |  | 146 |         $this->assertEquals(0, $coursecomp->get('grade'));
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 149 |         $this->assertEquals(0, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 150 |         $this->assertEquals(0, $usercomp2->get('grade'));
 | 
        
           |  |  | 151 |         $this->assertEquals(0, $coursecomp2->get('grade'));
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |         // Update the course module completion state to complete and trigger a competency update.
 | 
        
           |  |  | 154 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 155 |         $data->completionstate = COMPLETION_COMPLETE;
 | 
        
           |  |  | 156 |         $data->timemodified = time();
 | 
        
           |  |  | 157 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 |         // Comptency should now be complete for user, plan, and course now that the course module is completed.
 | 
        
           |  |  | 160 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 161 |         $this->assertEquals(1, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 162 |         $this->assertEquals(1, $usercomp->get('grade'));
 | 
        
           |  |  | 163 |         $this->assertEquals(1, $coursecomp->get('grade'));
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 166 |         $this->assertEquals(1, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 167 |         $this->assertEquals(1, $usercomp2->get('grade'));
 | 
        
           |  |  | 168 |         $this->assertEquals(1, $coursecomp2->get('grade'));
 | 
        
           |  |  | 169 |   | 
        
           |  |  | 170 |         // Change the competency completion for the user by adding evidence.
 | 
        
           |  |  | 171 |         api::add_evidence($this->user->id, $this->comp1, $this->context,
 | 
        
           |  |  | 172 |             evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 2);
 | 
        
           |  |  | 173 |         api::add_evidence($this->user->id, $this->comp2, $this->context,
 | 
        
           |  |  | 174 |             evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 2);
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 |         // After adding evidence, the competencies should now reflect the new grade value.
 | 
        
           |  |  | 177 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 178 |         $this->assertEquals(2, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 179 |         $this->assertEquals(2, $usercomp->get('grade'));
 | 
        
           |  |  | 180 |         $this->assertEquals(2, $coursecomp->get('grade'));
 | 
        
           |  |  | 181 |   | 
        
           |  |  | 182 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 183 |         $this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 184 |         $this->assertEquals(2, $usercomp2->get('grade'));
 | 
        
           |  |  | 185 |         $this->assertEquals(2, $coursecomp2->get('grade'));
 | 
        
           |  |  | 186 |   | 
        
           |  |  | 187 |         // Update the course module competency to incomplete. This will not change the competency status.
 | 
        
           |  |  | 188 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 189 |         $data->completionstate = COMPLETION_INCOMPLETE;
 | 
        
           |  |  | 190 |         $data->timemodified = time();
 | 
        
           |  |  | 191 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 192 |   | 
        
           |  |  | 193 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 194 |         $this->assertEquals(2, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 195 |         $this->assertEquals(2, $usercomp->get('grade'));
 | 
        
           |  |  | 196 |         $this->assertEquals(2, $coursecomp->get('grade'));
 | 
        
           |  |  | 197 |   | 
        
           |  |  | 198 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 199 |         $this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 200 |         $this->assertEquals(2, $usercomp2->get('grade'));
 | 
        
           |  |  | 201 |         $this->assertEquals(2, $coursecomp2->get('grade'));
 | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 |         // Re-complete the course module, so that it attempts to re-complete the competencies.
 | 
        
           |  |  | 204 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 205 |         $data->completionstate = COMPLETION_COMPLETE;
 | 
        
           |  |  | 206 |         $data->timemodified = time();
 | 
        
           |  |  | 207 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 208 |   | 
        
           |  |  | 209 |         // By default, this will not override the existing grade, so it should remain the same as before.
 | 
        
           |  |  | 210 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 211 |         $this->assertEquals(2, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 212 |         $this->assertEquals(2, $usercomp->get('grade'));
 | 
        
           |  |  | 213 |         $this->assertEquals(2, $coursecomp->get('grade'));
 | 
        
           |  |  | 214 |   | 
        
           |  |  | 215 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 216 |         $this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 217 |         $this->assertEquals(2, $usercomp2->get('grade'));
 | 
        
           |  |  | 218 |         $this->assertEquals(2, $coursecomp2->get('grade'));
 | 
        
           |  |  | 219 |   | 
        
           |  |  | 220 |         // Update the completion rule for only competency 1 to $overridegrade = true.
 | 
        
           |  |  | 221 |         $coursemodulecomps = api::list_course_module_competencies_in_course_module($this->cm);
 | 
        
           |  |  | 222 |         api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE,
 | 
        
           |  |  | 223 |             true);
 | 
        
           |  |  | 224 |   | 
        
           |  |  | 225 |         // Mark as incomplete then re-complete the course module.
 | 
        
           |  |  | 226 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 227 |         $data->completionstate = COMPLETION_INCOMPLETE;
 | 
        
           |  |  | 228 |         $data->timemodified = time();
 | 
        
           |  |  | 229 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 230 |   | 
        
           |  |  | 231 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 232 |         $data->completionstate = COMPLETION_COMPLETE;
 | 
        
           |  |  | 233 |         $data->timemodified = time();
 | 
        
           |  |  | 234 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 235 |   | 
        
           |  |  | 236 |         // Because the rule is now set to override existing grades, the grade should have now updated as per the ruleoutcome.
 | 
        
           |  |  | 237 |         // However the second competency didn't have this rule set, so it will not be overriden.
 | 
        
           |  |  | 238 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 239 |         $this->assertEquals(1, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 240 |         $this->assertEquals(1, $usercomp->get('grade'));
 | 
        
           |  |  | 241 |         $this->assertEquals(1, $coursecomp->get('grade'));
 | 
        
           |  |  | 242 |   | 
        
           |  |  | 243 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 244 |         $this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 245 |         $this->assertEquals(2, $usercomp2->get('grade'));
 | 
        
           |  |  | 246 |         $this->assertEquals(2, $coursecomp2->get('grade'));
 | 
        
           |  |  | 247 |   | 
        
           |  |  | 248 |         // If competency 2 is changed now to override and re-completed, it will update the same as competency 1.
 | 
        
           |  |  | 249 |         api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE,
 | 
        
           |  |  | 250 |             true);
 | 
        
           |  |  | 251 |   | 
        
           |  |  | 252 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 253 |         $data->completionstate = COMPLETION_INCOMPLETE;
 | 
        
           |  |  | 254 |         $data->timemodified = time();
 | 
        
           |  |  | 255 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 |         $data = $this->completion->get_data($this->cm, false, $this->user->id);
 | 
        
           |  |  | 258 |         $data->completionstate = COMPLETION_COMPLETE;
 | 
        
           |  |  | 259 |         $data->timemodified = time();
 | 
        
           |  |  | 260 |         $this->completion->internal_set_data($this->cm, $data);
 | 
        
           |  |  | 261 |   | 
        
           |  |  | 262 |         // Now both the competencies have $overridegrade = true,
 | 
        
           |  |  | 263 |         // they should both reflect the ruleoutcome after the completion above was processed.
 | 
        
           |  |  | 264 |         [$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
 | 
        
           |  |  | 265 |         $this->assertEquals(1, $plancomp->usercompetency->get('grade'));
 | 
        
           |  |  | 266 |         $this->assertEquals(1, $usercomp->get('grade'));
 | 
        
           |  |  | 267 |         $this->assertEquals(1, $coursecomp->get('grade'));
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |         [$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
 | 
        
           |  |  | 270 |         $this->assertEquals(1, $plancomp2->usercompetency->get('grade'));
 | 
        
           |  |  | 271 |         $this->assertEquals(1, $usercomp2->get('grade'));
 | 
        
           |  |  | 272 |         $this->assertEquals(1, $coursecomp2->get('grade'));
 | 
        
           |  |  | 273 |     }
 | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 |     /**
 | 
        
           |  |  | 276 |      * Test competency backup and restore correctly restores the ruleoutcome overridegrade value.
 | 
        
           |  |  | 277 |      *
 | 
        
           |  |  | 278 |      * @covers \core_competency\api::set_course_module_competency_ruleoutcome
 | 
        
           |  |  | 279 |      */
 | 
        
           |  |  | 280 |     public function test_override_backup_restore(): void {
 | 
        
           |  |  | 281 |         global $CFG;
 | 
        
           |  |  | 282 |         require_once($CFG->dirroot . '/course/externallib.php');
 | 
        
           |  |  | 283 |   | 
        
           |  |  | 284 |         // Set one to override grade and another to not override grade.
 | 
        
           |  |  | 285 |         $coursemodulecomps = api::list_course_module_competencies_in_course_module($this->cm);
 | 
        
           |  |  | 286 |         api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE,
 | 
        
           |  |  | 287 |             false);
 | 
        
           |  |  | 288 |         api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE,
 | 
        
           |  |  | 289 |             true);
 | 
        
           |  |  | 290 |   | 
        
           |  |  | 291 |         // Duplicate the course (backup and restore).
 | 
        
           |  |  | 292 |         $duplicated = \core_course_external::duplicate_course($this->course->id, 'test', 'test', $this->course->category);
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 |         // Get the new course modules.
 | 
        
           |  |  | 295 |         $newcoursemodules = get_coursemodules_in_course('label', $duplicated['id']);
 | 
        
           |  |  | 296 |         $this->assertCount(1, $newcoursemodules);
 | 
        
           |  |  | 297 |         $cm = array_pop($newcoursemodules);
 | 
        
           |  |  | 298 |   | 
        
           |  |  | 299 |         // Get the comeptencies for this cm.
 | 
        
           |  |  | 300 |         $newcoursemodulecomps = api::list_course_module_competencies_in_course_module($cm);
 | 
        
           |  |  | 301 |         $this->assertCount(2, $newcoursemodulecomps);
 | 
        
           |  |  | 302 |   | 
        
           |  |  | 303 |         // Ensure the override grade settings are restored properly.
 | 
        
           |  |  | 304 |         $this->assertEquals($coursemodulecomps[0]->get('overridegrade'), $newcoursemodulecomps[0]->get('overridegrade'));
 | 
        
           |  |  | 305 |         $this->assertEquals($coursemodulecomps[1]->get('overridegrade'), $newcoursemodulecomps[1]->get('overridegrade'));
 | 
        
           |  |  | 306 |     }
 | 
        
           |  |  | 307 |   | 
        
           |  |  | 308 |     /**
 | 
        
           |  |  | 309 |      * Gets the course, user and plan competency for the given competency ID
 | 
        
           |  |  | 310 |      *
 | 
        
           |  |  | 311 |      * @param int $compid ID of the competency.
 | 
        
           |  |  | 312 |      * @return array array containing the three related competencies
 | 
        
           |  |  | 313 |      */
 | 
        
           |  |  | 314 |     private function get_related_competencies(int $compid): array {
 | 
        
           |  |  | 315 |         $coursecomp = api::get_user_competency_in_course($this->course->id, $this->user->id, $compid);
 | 
        
           |  |  | 316 |         $usercomp = api::get_user_competency($this->user->id, $compid);
 | 
        
           |  |  | 317 |         $plancomp = api::get_plan_competency($this->plan, $compid);
 | 
        
           |  |  | 318 |         return [$coursecomp, $plancomp, $usercomp];
 | 
        
           |  |  | 319 |     }
 | 
        
           |  |  | 320 | }
 |