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.

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

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