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/**
18 * Restore dates test case.
19 *
20 * @package    core
21 * @category   test
22 * @copyright  2017 onwards Ankit Agarwal
23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
29require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
30
31
32/**
33 * Advanced PHPUnit test case customised for testing restore dates in Moodle.
34 *
35 * @package    core
36 * @category   test
37 * @copyright  2017 onwards Ankit Agarwal
38 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 */
40abstract class restore_date_testcase extends advanced_testcase {
41    /**
42     * @var int Course start date.
43     */
44    protected $startdate;
45
46    /**
47     * @var int Course restore date.
48     */
49    protected $restorestartdate;
50
51    /**
52     * Setup.
53     */
54    public function setUp(): void {
55        global $CFG;
56
57        parent::setUp();
58        $this->resetAfterTest();
59        $this->setAdminUser();
60        $this->startdate = strtotime('1 Jan 2017 00:00 GMT');
61        $this->restorestartdate = strtotime('1 Feb 2017 00:00 GMT');
62        $CFG->enableavailability = true;
63    }
64
65    /**
66     * Backs a course up and restores it.
67     *
68     * @param stdClass $course Course object to backup
69     * @param int $newdate If non-zero, specifies custom date for new course
70     * @return int ID of newly restored course
71     */
72    protected function backup_and_restore($course, $newdate = 0) {
73        global $USER, $CFG;
74
75        // Turn off file logging, otherwise it can't delete the file (Windows).
76        $CFG->backup_file_logger_level = backup::LOG_NONE;
77
78        // Do backup with default settings.
79        set_config('backup_general_users', 1, 'backup');
80        $bc = new backup_controller(backup::TYPE_1COURSE, $course->id,
81            backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL,
82            $USER->id);
83        $bc->execute_plan();
84        $results = $bc->get_results();
85        $file = $results['backup_destination'];
86        $fp = get_file_packer('application/vnd.moodle.backup');
87        $filepath = $CFG->dataroot . '/temp/backup/test-restore-course';
88        $file->extract_to_pathname($fp, $filepath);
89        $bc->destroy();
90
91        // Do restore to new course with default settings.
92        $newcourseid = restore_dbops::create_new_course(
93            $course->fullname, $course->shortname . '_2', $course->category);
94        $rc = new restore_controller('test-restore-course', $newcourseid,
95            backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id,
96            backup::TARGET_NEW_COURSE);
97
98        if (empty($newdate)) {
99            $newdate = $this->restorestartdate;
100        }
101
102        $rc->get_plan()->get_setting('course_startdate')->set_value($newdate);
103        $this->assertTrue($rc->execute_precheck());
104        $rc->execute_plan();
105        $rc->destroy();
106
107        return $newcourseid;
108    }
109
110    /**
111     * Helper method to create a course and a module.
112     *
113     * @param string $modulename
114     * @param array|stdClass $record
115     * @return array
116     */
117    protected function create_course_and_module($modulename, $record = []) {
118        // Create a course with specific start date.
119        $record = (array)$record;
120        $generator = $this->getDataGenerator();
121        $course = $generator->create_course(['startdate' => $this->startdate]);
122        $record = array_merge(['course' => $course->id], $record);
123        $module = $this->getDataGenerator()->create_module($modulename, $record);
124        return [$course, $module];
125    }
126
127    /**
128     * Verify that the given properties are not rolled.
129     *
130     * @param stdClass $oldinstance
131     * @param stdClass $newinstance
132     * @param [] $props
133     */
134    protected function assertFieldsNotRolledForward($oldinstance, $newinstance, $props) {
135        foreach ($props as $prop) {
136            $this->assertEquals($oldinstance->$prop, $newinstance->$prop, "'$prop' should not roll forward.");
137        }
138    }
139
140    /**
141     * Verify that the given properties are rolled.
142     *
143     * @param stdClass $oldinstance
144     * @param stdClass $newinstance
145     * @param [] $props
146     */
147    protected function assertFieldsRolledForward($oldinstance, $newinstance, $props) {
148        $diff = $this->get_diff();
149        foreach ($props as $prop) {
150            $this->assertEquals(($oldinstance->$prop + $diff), $newinstance->$prop, "'$prop' doesn't roll as expected.");
151        }
152    }
153
154    /**
155     * Get time diff between start date and restore date in seconds.
156     *
157     * @return mixed
158     */
159    protected function get_diff() {
160        return ($this->restorestartdate - $this->startdate);
161    }
162
163}
164