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 * Provides \core\update\testable_checker class.
19 *
20 * @package     core_plugin
21 * @subpackage  fixtures
22 * @category    test
23 * @copyright   2012, 2015 David Mudrak <david@moodle.com>
24 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26namespace core\update;
27
28defined('MOODLE_INTERNAL') || die();
29
30/**
31 * Modified version of {@link \core\update\checker} suitable for testing.
32 *
33 * @copyright 2012, 2015 David Mudrak <david@moodle.com>
34 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 */
36class testable_checker extends checker {
37
38    /** @var replaces the default DB table storage for the fetched response */
39    protected $fakeresponsestorage;
40    /** @var int stores the fake recentfetch value */
41    public $fakerecentfetch = -1;
42    /** @var int stores the fake value of time() */
43    public $fakecurrenttimestamp = -1;
44
45    /**
46     * Factory method for this class.
47     *
48     * @return \core\update\testable_checker the singleton instance
49     */
50    public static function instance() {
51        global $CFG;
52
53        if (is_null(self::$singletoninstance)) {
54            self::$singletoninstance = new self();
55        }
56        return self::$singletoninstance;
57    }
58
59    protected function validate_response($response) {
60    }
61
62    protected function store_response($response) {
63        $this->fakeresponsestorage = $response;
64    }
65
66    protected function restore_response($forcereload = false) {
67        $this->recentfetch = time();
68        $this->recentresponse = $this->decode_response($this->get_fake_response());
69    }
70
71    public function compare_responses(array $old, array $new) {
72        return parent::compare_responses($old, $new);
73    }
74
75    public function is_same_release($remote, $local=null) {
76        return parent::is_same_release($remote, $local);
77    }
78
79    protected function load_current_environment($forcereload=false) {
80    }
81
82    public function fake_current_environment($version, $release, $branch, array $plugins) {
83        $this->currentversion = $version;
84        $this->currentrelease = $release;
85        $this->currentbranch = $branch;
86        $this->currentplugins = $plugins;
87    }
88
89    public function get_last_timefetched() {
90        if ($this->fakerecentfetch == -1) {
91            return parent::get_last_timefetched();
92        } else {
93            return $this->fakerecentfetch;
94        }
95    }
96
97    private function get_fake_response() {
98        $fakeresponse = array(
99            'status' => 'OK',
100            'provider' => 'https://download.moodle.org/api/1.0/updates.php',
101            'apiver' => '1.0',
102            'timegenerated' => time(),
103            'forversion' => '2012010100.00',
104            'forbranch' => '2.3',
105            'ticket' => sha1('No, I am not going to mention the word "frog" here. Oh crap. I just did.'),
106            'updates' => array(
107                'core' => array(
108                    array(
109                        'version' => 2012060103.00,
110                        'release' => '2.3.3 (Build: 20121201)',
111                        'maturity' => 200,
112                        'url' => 'https://download.moodle.org/',
113                        'download' => 'https://download.moodle.org/download.php/MOODLE_23_STABLE/moodle-2.3.3-latest.zip',
114                    ),
115                    array(
116                        'version' => 2012120100.00,
117                        'release' => '2.4dev (Build: 20121201)',
118                        'maturity' => 50,
119                        'url' => 'https://download.moodle.org/',
120                        'download' => 'https://download.moodle.org/download.php/MOODLE_24_STABLE/moodle-2.4.0-latest.zip',
121                    ),
122                ),
123                'mod_foo' => array(
124                    array(
125                        'version' => 2012030501,
126                        'requires' => 2012010100,
127                        'maturity' => 200,
128                        'release' => '1.1',
129                        'url' => 'http://moodle.org/plugins/blahblahblah/',
130                        'download' => 'http://moodle.org/plugins/download.php/blahblahblah',
131                    ),
132                    array(
133                        'version' => 2012030502,
134                        'requires' => 2012010100,
135                        'maturity' => 100,
136                        'release' => '1.2 beta',
137                        'url' => 'http://moodle.org/plugins/',
138                    ),
139                ),
140            ),
141        );
142
143        return json_encode($fakeresponse);
144    }
145
146    protected function cron_current_timestamp() {
147        if ($this->fakecurrenttimestamp == -1) {
148            return parent::cron_current_timestamp();
149        } else {
150            return $this->fakecurrenttimestamp;
151        }
152    }
153
154    protected function cron_mtrace($msg, $eol = PHP_EOL) {
155    }
156
157    protected function cron_autocheck_enabled() {
158        return true;
159    }
160
161    protected function cron_execution_offset() {
162        // Autofetch should run by the first cron after 01:42 AM.
163        return 42 * MINSECS;
164    }
165
166    protected function cron_execute() {
167        throw new testable_checker_cron_executed('Cron executed!');
168    }
169}
170
171
172/**
173 * Exception used to detect {@link checker::cron_execute()} calls.
174 *
175 * @copyright 2012, 2015 David Mudrak <david@moodle.com>
176 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
177 */
178class testable_checker_cron_executed extends \Exception {
179}
180