Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   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_backup;
  18  
  19  use async_helper;
  20  use backup;
  21  use backup_controller;
  22  
  23  defined('MOODLE_INTERNAL') || die();
  24  
  25  global $CFG;
  26  require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
  27  require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
  28  
  29  /**
  30   * Asyncronhous helper tests.
  31   *
  32   * @package    core_backup
  33   * @copyright  2018 Matt Porritt <mattp@catalyst-au.net>
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class async_helper_test extends \advanced_testcase {
  37  
  38      /**
  39       * Tests sending message for asynchronous backup.
  40       */
  41      public function test_send_message() {
  42          global $DB, $USER;
  43          $this->preventResetByRollback();
  44          $this->resetAfterTest(true);
  45          $this->setAdminUser();
  46  
  47          set_config('backup_async_message_users', '1', 'backup');
  48          set_config('backup_async_message_subject', 'Moodle {operation} completed sucessfully', 'backup');
  49          set_config('backup_async_message',
  50                  'Dear {user_firstname} {user_lastname}, <br/> Your {operation} (ID: {backupid}) has completed successfully!',
  51                  'backup');
  52          set_config('allowedemaildomains', 'example.com');
  53  
  54          $generator = $this->getDataGenerator();
  55          $course = $generator->create_course();  // Create a course with some availability data set.
  56          $user2 = $generator->create_user(array('firstname' => 'test', 'lastname' => 'human', 'maildisplay' => 1));
  57          $generator->enrol_user($user2->id, $course->id, 'editingteacher');
  58  
  59          $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'");
  60          set_user_preference('message_provider_moodle_asyncbackupnotification', 'email', $user2);
  61  
  62          // Make the backup controller for an async backup.
  63          $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
  64                  backup::INTERACTIVE_YES, backup::MODE_ASYNC, $user2->id);
  65          $bc->finish_ui();
  66          $backupid = $bc->get_backupid();
  67          $bc->destroy();
  68  
  69          $sink = $this->redirectEmails();
  70  
  71          // Send message.
  72          $asynchelper = new async_helper('backup', $backupid);
  73          $messageid = $asynchelper->send_message();
  74  
  75          $emails = $sink->get_messages();
  76          $this->assertCount(1, $emails);
  77          $email = reset($emails);
  78  
  79          $this->assertSame($USER->email, $email->from);
  80          $this->assertSame($user2->email, $email->to);
  81          $this->assertSame('Moodle backup completed sucessfully', $email->subject);
  82          $this->assertNotEmpty($email->header);
  83          $this->assertNotEmpty($email->body);
  84          $this->assertMatchesRegularExpression("/$backupid/", $email->body);
  85          $this->assertThat($email->body, $this->logicalNot($this->stringContains('{')));
  86          $this->assertGreaterThan(0, $messageid);
  87          $sink->clear();
  88      }
  89  
  90      /**
  91       * Tests getting the asynchronous backup table items.
  92       */
  93      public function test_get_async_backups() {
  94          global $DB, $CFG, $USER, $PAGE;
  95  
  96          $this->resetAfterTest(true);
  97          $this->setAdminUser();
  98          $CFG->enableavailability = true;
  99          $CFG->enablecompletion = true;
 100  
 101          // Create a course with some availability data set.
 102          $generator = $this->getDataGenerator();
 103          $course = $generator->create_course(
 104              array('format' => 'topics', 'numsections' => 3,
 105                  'enablecompletion' => COMPLETION_ENABLED),
 106              array('createsections' => true));
 107          $forum = $generator->create_module('forum', array(
 108              'course' => $course->id));
 109          $forum2 = $generator->create_module('forum', array(
 110              'course' => $course->id, 'completion' => COMPLETION_TRACKING_MANUAL));
 111  
 112          // We need a grade, easiest is to add an assignment.
 113          $assignrow = $generator->create_module('assign', array(
 114              'course' => $course->id));
 115          $assign = new \assign(\context_module::instance($assignrow->cmid), false, false);
 116          $item = $assign->get_grade_item();
 117  
 118          // Make a test grouping as well.
 119          $grouping = $generator->create_grouping(array('courseid' => $course->id,
 120              'name' => 'Grouping!'));
 121  
 122          $availability = '{"op":"|","show":false,"c":[' .
 123              '{"type":"completion","cm":' . $forum2->cmid .',"e":1},' .
 124              '{"type":"grade","id":' . $item->id . ',"min":4,"max":94},' .
 125              '{"type":"grouping","id":' . $grouping->id . '}' .
 126              ']}';
 127          $DB->set_field('course_modules', 'availability', $availability, array(
 128              'id' => $forum->cmid));
 129          $DB->set_field('course_sections', 'availability', $availability, array(
 130              'course' => $course->id, 'section' => 1));
 131  
 132          // Make the backup controller for an async backup.
 133          $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
 134              backup::INTERACTIVE_YES, backup::MODE_ASYNC, $USER->id);
 135          $bc->finish_ui();
 136          $bc->destroy();
 137          unset($bc);
 138  
 139          $coursecontext = \context_course::instance($course->id);
 140          $renderer = $PAGE->get_renderer('core', 'backup');
 141  
 142          $result = \async_helper::get_async_backups($renderer, $coursecontext->instanceid);
 143  
 144          $this->assertEquals(1, count($result));
 145          $this->assertEquals('backup.mbz', $result[0][0]);
 146      }
 147  
 148      /**
 149       * Tests getting the backup record.
 150       */
 151      public function test_get_backup_record() {
 152          global $USER;
 153  
 154          $this->resetAfterTest();
 155          $this->setAdminUser();
 156          $generator = $this->getDataGenerator();
 157          $course = $generator->create_course();
 158  
 159          // Create the initial backupcontoller.
 160          $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id, \backup::FORMAT_MOODLE,
 161              \backup::INTERACTIVE_NO, \backup::MODE_COPY, $USER->id, \backup::RELEASESESSION_YES);
 162          $backupid = $bc->get_backupid();
 163          $bc->destroy();
 164          $copyrec = \async_helper::get_backup_record($backupid);
 165  
 166          $this->assertEquals($backupid, $copyrec->backupid);
 167  
 168      }
 169  
 170      /**
 171       * Tests is async pending conditions.
 172       */
 173      public function test_is_async_pending() {
 174          global $USER;
 175  
 176          $this->resetAfterTest();
 177          $this->setAdminUser();
 178          $generator = $this->getDataGenerator();
 179          $course = $generator->create_course();
 180  
 181          set_config('enableasyncbackup', '0');
 182          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 183  
 184          // Should be false as there are no backups and async backup is false.
 185          $this->assertFalse($ispending);
 186  
 187          // Create the initial backupcontoller.
 188          $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id, \backup::FORMAT_MOODLE,
 189              \backup::INTERACTIVE_NO, \backup::MODE_ASYNC, $USER->id, \backup::RELEASESESSION_YES);
 190          $bc->destroy();
 191          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 192  
 193          // Should be false as there as async backup is false.
 194          $this->assertFalse($ispending);
 195  
 196          set_config('enableasyncbackup', '1');
 197          // Should be true as there as async backup is true and there is a pending backup.
 198          $this->assertFalse($ispending);
 199      }
 200  
 201      /**
 202       * Tests is async pending conditions for course copies.
 203       */
 204      public function test_is_async_pending_copy() {
 205          global $USER;
 206  
 207          $this->resetAfterTest();
 208          $this->setAdminUser();
 209          $generator = $this->getDataGenerator();
 210          $course = $generator->create_course();
 211  
 212          set_config('enableasyncbackup', '0');
 213          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 214  
 215          // Should be false as there are no copies and async backup is false.
 216          $this->assertFalse($ispending);
 217  
 218          // Create the initial backupcontoller.
 219          $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id, \backup::FORMAT_MOODLE,
 220              \backup::INTERACTIVE_NO, \backup::MODE_COPY, $USER->id, \backup::RELEASESESSION_YES);
 221          $bc->destroy();
 222          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 223  
 224          // Should be True as this a copy operation.
 225          $this->assertTrue($ispending);
 226  
 227          set_config('enableasyncbackup', '1');
 228          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 229  
 230          // Should be true as there as async backup is true and there is a pending copy.
 231          $this->assertTrue($ispending);
 232      }
 233  
 234  }