Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

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

   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          $renderer = $PAGE->get_renderer('core', 'backup');
 144  
 145          $result = \async_helper::get_async_backups($renderer, $coursecontext->instanceid);
 146  
 147          $this->assertEquals(1, count($result));
 148          $this->assertEquals('backup.mbz', $result[0][0]);
 149      }
 150  
 151      /**
 152       * Tests getting the backup record.
 153       */
 154      public function test_get_backup_record() {
 155          global $USER;
 156  
 157          $this->resetAfterTest();
 158          $this->setAdminUser();
 159          $generator = $this->getDataGenerator();
 160          $course = $generator->create_course();
 161  
 162          // Create the initial backupcontoller.
 163          $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id, \backup::FORMAT_MOODLE,
 164              \backup::INTERACTIVE_NO, \backup::MODE_COPY, $USER->id, \backup::RELEASESESSION_YES);
 165          $backupid = $bc->get_backupid();
 166          $bc->destroy();
 167          $copyrec = \async_helper::get_backup_record($backupid);
 168  
 169          $this->assertEquals($backupid, $copyrec->backupid);
 170  
 171      }
 172  
 173      /**
 174       * Tests is async pending conditions.
 175       */
 176      public function test_is_async_pending() {
 177          global $USER;
 178  
 179          $this->resetAfterTest();
 180          $this->setAdminUser();
 181          $generator = $this->getDataGenerator();
 182          $course = $generator->create_course();
 183  
 184          set_config('enableasyncbackup', '0');
 185          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 186  
 187          // Should be false as there are no backups and async backup is false.
 188          $this->assertFalse($ispending);
 189  
 190          // Create the initial backupcontoller.
 191          $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id, \backup::FORMAT_MOODLE,
 192              \backup::INTERACTIVE_NO, \backup::MODE_ASYNC, $USER->id, \backup::RELEASESESSION_YES);
 193          $bc->destroy();
 194          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 195  
 196          // Should be false as there as async backup is false.
 197          $this->assertFalse($ispending);
 198  
 199          set_config('enableasyncbackup', '1');
 200          // Should be true as there as async backup is true and there is a pending backup.
 201          $this->assertFalse($ispending);
 202      }
 203  
 204      /**
 205       * Tests is async pending conditions for course copies.
 206       */
 207      public function test_is_async_pending_copy() {
 208          global $USER;
 209  
 210          $this->resetAfterTest();
 211          $this->setAdminUser();
 212          $generator = $this->getDataGenerator();
 213          $course = $generator->create_course();
 214  
 215          set_config('enableasyncbackup', '0');
 216          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 217  
 218          // Should be false as there are no copies and async backup is false.
 219          $this->assertFalse($ispending);
 220  
 221          // Create the initial backupcontoller.
 222          $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id, \backup::FORMAT_MOODLE,
 223              \backup::INTERACTIVE_NO, \backup::MODE_COPY, $USER->id, \backup::RELEASESESSION_YES);
 224          $bc->destroy();
 225          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 226  
 227          // Should be True as this a copy operation.
 228          $this->assertTrue($ispending);
 229  
 230          set_config('enableasyncbackup', '1');
 231          $ispending = async_helper::is_async_pending($course->id, 'course', 'backup');
 232  
 233          // Should be true as there as async backup is true and there is a pending copy.
 234          $this->assertTrue($ispending);
 235      }
 236  
 237  }