Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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\task;
  18  
  19  use core_competency\api;
  20  use core_competency\plan;
  21  use core_competency\template;
  22  
  23  /**
  24   * Task tests.
  25   *
  26   * @package    core_competency
  27   * @copyright  2015 Issam Taboubi <issam.taboubi@umontreal.ca>
  28   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29   */
  30  class task_test extends \advanced_testcase {
  31  
  32      public function test_sync_plans_from_cohorts_task() {
  33          global $DB;
  34  
  35          $this->resetAfterTest(true);
  36          $this->setAdminUser();
  37          $dg = $this->getDataGenerator();
  38          $lpg = $dg->get_plugin_generator('core_competency');
  39  
  40          // Sql to simulate the execution in time.
  41          $cmsql = "UPDATE {cohort_members} SET timeadded = :currenttime WHERE cohortid = :cohortid AND userid = :userid";
  42          $tplsql = "UPDATE {" . template::TABLE . "} SET timemodified = :currenttime WHERE id = :templateid";
  43          $plansql = "UPDATE {" . plan::TABLE . "} SET timemodified = :currenttime WHERE id = :planid";
  44  
  45          $currenttime = time();
  46  
  47          $user1 = $dg->create_user();
  48          $user2 = $dg->create_user();
  49          $user3 = $dg->create_user();
  50          $user4 = $dg->create_user();
  51          $user5 = $dg->create_user();
  52  
  53          $cohort = $dg->create_cohort();
  54          $tpl = $lpg->create_template();
  55  
  56          // Add 2 users to the cohort.
  57          cohort_add_member($cohort->id, $user1->id);
  58          cohort_add_member($cohort->id, $user2->id);
  59  
  60          // Creating plans from template cohort.
  61          $templatecohort = api::create_template_cohort($tpl->get('id'), $cohort->id);
  62          $created = api::create_plans_from_template_cohort($tpl->get('id'), $cohort->id);
  63  
  64          $this->assertEquals(2, $created);
  65  
  66          $task = \core\task\manager::get_scheduled_task('\\core\\task\\sync_plans_from_template_cohorts_task');
  67          $this->assertInstanceOf('\core\task\sync_plans_from_template_cohorts_task', $task);
  68  
  69          // Add two more users to the cohort.
  70          cohort_add_member($cohort->id, $user3->id);
  71          cohort_add_member($cohort->id, $user4->id);
  72  
  73          $currenttime = $currenttime + 1;
  74          $task->execute();
  75          $task->set_last_run_time($currenttime);
  76  
  77          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
  78  
  79          // Test if remove user from cohort will affect plans.
  80          cohort_remove_member($cohort->id, $user3->id);
  81          cohort_remove_member($cohort->id, $user4->id);
  82  
  83          $currenttime = $currenttime + 1;
  84          $task->execute();
  85          $task->set_last_run_time($currenttime);
  86          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
  87  
  88          // The template is now hidden, and I've added a user with a missing plan. Nothing should happen.
  89          $currenttime = $currenttime + 1;
  90          $tpl->set('visible', false);
  91          $tpl->update();
  92          $DB->execute($tplsql, array('currenttime' => $currenttime, 'templateid' => $tpl->get('id')));
  93          $currenttime = $currenttime + 1;
  94          cohort_add_member($cohort->id, $user5->id);
  95          $DB->execute($cmsql, array('currenttime' => $currenttime, 'cohortid' => $cohort->id, 'userid' => $user5->id));
  96          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
  97          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
  98          $currenttime = $currenttime + 1;
  99          $task->execute();
 100          $task->set_last_run_time($currenttime);
 101          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 102          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 103  
 104          // Now I set the template as visible again, the plan is created.
 105          $currenttime = $currenttime + 1;
 106          $tpl->set('visible', true);
 107          $tpl->update();
 108          $DB->execute($tplsql, array('currenttime' => $currenttime, 'templateid' => $tpl->get('id')));
 109          $currenttime = $currenttime + 1;
 110          $task->execute();
 111          $task->set_last_run_time($currenttime);
 112          $this->assertTrue(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 113          $this->assertEquals(5, plan::count_records(array('templateid' => $tpl->get('id'))));
 114  
 115          // Let's unlink the plan and run the task again, it should not be recreated.
 116          $currenttime = $currenttime + 1;
 117          $plan = plan::get_record(array('userid' => $user5->id, 'templateid' => $tpl->get('id')));
 118          api::unlink_plan_from_template($plan);
 119          $DB->execute($plansql, array('currenttime' => $currenttime, 'planid' => $plan->get('id')));
 120          $this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
 121          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 122          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 123          $currenttime = $currenttime + 1;
 124          $task->execute();
 125          $task->set_last_run_time($currenttime);
 126          $this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
 127          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 128          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 129  
 130          // Adding users to cohort that already exist in plans.
 131          $currenttime = $currenttime + 1;
 132          cohort_add_member($cohort->id, $user3->id);
 133          cohort_add_member($cohort->id, $user4->id);
 134          $DB->execute($cmsql, array('currenttime' => $currenttime, 'cohortid' => $cohort->id, 'userid' => $user3->id));
 135          $DB->execute($cmsql, array('currenttime' => $currenttime, 'cohortid' => $cohort->id, 'userid' => $user3->id));
 136  
 137          $currenttime = $currenttime + 1;
 138          $task->execute();
 139          $task->set_last_run_time($currenttime);
 140          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 141  
 142          // Test a user plan deleted will not be recreated.
 143          $currenttime = $currenttime + 1;
 144          $plan = plan::get_record(array('userid' => $user4->id, 'templateid' => $tpl->get('id')));
 145          api::delete_plan($plan->get('id'));
 146          $currenttime = $currenttime + 1;
 147          $task->execute();
 148          $task->set_last_run_time($currenttime);
 149          $this->assertEquals(3, plan::count_records(array('templateid' => $tpl->get('id'))));
 150      }
 151  
 152      public function test_sync_plans_from_cohorts_with_templateduedate_task() {
 153          $this->resetAfterTest(true);
 154          $this->setAdminUser();
 155          $dg = $this->getDataGenerator();
 156          $lpg = $dg->get_plugin_generator('core_competency');
 157  
 158          $user1 = $dg->create_user();
 159          $user2 = $dg->create_user();
 160          $user3 = $dg->create_user();
 161          $user4 = $dg->create_user();
 162          $user5 = $dg->create_user();
 163  
 164          $cohort = $dg->create_cohort();
 165          $tpl = $lpg->create_template(array('duedate' => time() + 400));
 166  
 167          // Add 2 users to the cohort.
 168          cohort_add_member($cohort->id, $user1->id);
 169          cohort_add_member($cohort->id, $user2->id);
 170  
 171          // Creating plans from template cohort.
 172          $templatecohort = api::create_template_cohort($tpl->get('id'), $cohort->id);
 173          $created = api::create_plans_from_template_cohort($tpl->get('id'), $cohort->id);
 174  
 175          $this->assertEquals(2, $created);
 176  
 177          $task = \core\task\manager::get_scheduled_task('\\core\\task\\sync_plans_from_template_cohorts_task');
 178          $this->assertInstanceOf('\core\task\sync_plans_from_template_cohorts_task', $task);
 179  
 180          // Add two more users to the cohort.
 181          cohort_add_member($cohort->id, $user3->id);
 182          cohort_add_member($cohort->id, $user4->id);
 183  
 184          $task->execute();
 185  
 186          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 187  
 188          // Test if remove user from cohort will affect plans.
 189          cohort_remove_member($cohort->id, $user3->id);
 190          cohort_remove_member($cohort->id, $user4->id);
 191  
 192          $task->execute();
 193          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 194  
 195          // The template is now hidden, and I've added a user with a missing plan. Nothing should happen.
 196          $tpl->set('visible', false);
 197          $tpl->update();
 198          cohort_add_member($cohort->id, $user5->id);
 199          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 200          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 201          $task->execute();
 202          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 203          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 204  
 205          // Now I set the template as visible again, the plan is created.
 206          $tpl->set('visible', true);
 207          $tpl->update();
 208          $task->execute();
 209          $this->assertTrue(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 210          $this->assertEquals(5, plan::count_records(array('templateid' => $tpl->get('id'))));
 211  
 212          // Let's unlink the plan and run the task again, it should not be recreated.
 213          $plan = plan::get_record(array('userid' => $user5->id, 'templateid' => $tpl->get('id')));
 214          api::unlink_plan_from_template($plan);
 215          $this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
 216          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 217          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 218          $task->execute();
 219          $this->assertTrue(plan::record_exists_select('userid = ?', array($user5->id)));
 220          $this->assertFalse(plan::record_exists_select('userid = ? AND templateid = ?', array($user5->id, $tpl->get('id'))));
 221          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 222  
 223          // Adding users to cohort that already exist in plans.
 224          cohort_add_member($cohort->id, $user3->id);
 225          cohort_add_member($cohort->id, $user4->id);
 226  
 227          $task->execute();
 228          $this->assertEquals(4, plan::count_records(array('templateid' => $tpl->get('id'))));
 229      }
 230  
 231      public function test_sync_plans_from_cohorts_with_passed_duedate() {
 232          global $DB;
 233  
 234          $this->resetAfterTest(true);
 235          $this->setAdminUser();
 236          $dg = $this->getDataGenerator();
 237          $lpg = $dg->get_plugin_generator('core_competency');
 238  
 239          $user1 = $dg->create_user();
 240          $user2 = $dg->create_user();
 241          $cohort = $dg->create_cohort();
 242          $tpl = $lpg->create_template(array('duedate' => time() + 1000));
 243          $templatecohort = api::create_template_cohort($tpl->get('id'), $cohort->id);
 244          $task = \core\task\manager::get_scheduled_task('\\core\\task\\sync_plans_from_template_cohorts_task');
 245  
 246          // Add 1 user to the cohort.
 247          cohort_add_member($cohort->id, $user1->id);
 248  
 249          // Creating plans from template cohort.
 250          $task->execute();
 251          $this->assertEquals(1, plan::count_records());
 252  
 253          // Now add another user, but this time the template will be expired.
 254          cohort_add_member($cohort->id, $user2->id);
 255          $record = $tpl->to_record();
 256          $record->duedate = time() - 10000;
 257          $DB->update_record(template::TABLE, $record);
 258          $tpl->read();
 259          $task->execute();
 260          $this->assertEquals(1, plan::count_records()); // Still only one plan.
 261  
 262          // Pretend it wasn't expired.
 263          $tpl->set('duedate', time() + 100);
 264          $tpl->update();
 265          $task->execute();
 266          $this->assertEquals(2, plan::count_records()); // Now there is two.
 267      }
 268  
 269      public function test_complete_plans_task() {
 270          global $DB;
 271          $this->resetAfterTest(true);
 272          $this->setAdminUser();
 273          $dg = $this->getDataGenerator();
 274          $lpg = $dg->get_plugin_generator('core_competency');
 275  
 276          $user = $dg->create_user();
 277  
 278          $up1 = $lpg->create_plan(array('userid' => $user->id,
 279                                          'status' => plan::STATUS_DRAFT));
 280          $up2 = $lpg->create_plan(array('userid' => $user->id,
 281                                          'status' => plan::STATUS_ACTIVE));
 282          // Set duedate in the past.
 283          $date = new \DateTime('yesterday');
 284          $record1 = $up1->to_record();
 285          $record2 = $up2->to_record();
 286  
 287          $record1->duedate = $date->getTimestamp();
 288          $record2->duedate = $date->getTimestamp();
 289          $DB->update_record(plan::TABLE, $record1);
 290          $DB->update_record(plan::TABLE, $record2);
 291  
 292          $task = \core\task\manager::get_scheduled_task('\\core\\task\\complete_plans_task');
 293          $this->assertInstanceOf('\\core\\task\\complete_plans_task', $task);
 294  
 295          // Test that draft plan can not be completed on running task.
 296          $task->execute();
 297  
 298          $plandraft = api::read_plan($up1->get('id'));
 299          $this->assertEquals(plan::STATUS_DRAFT, $plandraft->get('status'));
 300  
 301          // Test that active plan can be completed on running task.
 302          $task->execute();
 303  
 304          $planactive = api::read_plan($up2->get('id'));
 305          $this->assertEquals(plan::STATUS_COMPLETE, $planactive->get('status'));
 306      }
 307  }