Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 tool_recyclebin;
18
 
19
/**
20
 * Recycle bin category tests.
21
 *
22
 * @package    tool_recyclebin
23
 * @copyright  2015 University of Kent
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1441 ariadna 25
 * @covers     \tool_recyclebin\category_bin
1 efrain 26
 */
1441 ariadna 27
final class category_bin_test extends \advanced_testcase {
1 efrain 28
 
29
    /**
30
     * @var \stdClass $course
31
     */
32
    protected $course;
33
 
34
    /**
35
     * @var \stdClass $coursebeingrestored
36
     */
37
    protected $coursebeingrestored;
38
 
39
    /**
40
     * Setup for each test.
41
     */
42
    protected function setUp(): void {
1441 ariadna 43
        parent::setUp();
1 efrain 44
        $this->resetAfterTest();
45
        $this->setAdminUser();
46
 
47
        // We want the category bin to be enabled.
48
        set_config('categorybinenable', 1, 'tool_recyclebin');
49
 
50
        $this->course = $this->getDataGenerator()->create_course();
51
    }
52
 
53
    /**
54
     * Check that our hook is called when a course is deleted.
55
     */
11 efrain 56
    public function test_pre_course_delete_hook(): void {
1 efrain 57
        global $DB;
58
 
59
        // This simulates a temporary course being cleaned up by a course restore.
60
        $this->coursebeingrestored = $this->getDataGenerator()->create_course();
61
        $this->coursebeingrestored->deletesource = 'restore';
62
 
63
        // Should have nothing in the recycle bin.
64
        $this->assertEquals(0, $DB->count_records('tool_recyclebin_category'));
65
 
66
        delete_course($this->course, false);
67
        // This should not be added to the recycle bin.
68
        delete_course($this->coursebeingrestored, false);
69
 
70
        // Check the course is now in the recycle bin.
71
        $this->assertEquals(1, $DB->count_records('tool_recyclebin_category'));
72
 
73
        // Try with the API.
74
        $recyclebin = new \tool_recyclebin\category_bin($this->course->category);
75
        $this->assertEquals(1, count($recyclebin->get_items()));
76
    }
77
 
1441 ariadna 78
    public function test_delete_course_with_long_names(): void {
79
        global $DB;
80
 
81
        // Create a course with its name at the upper limit of what is allowed.
82
        $course = $this->getDataGenerator()->create_course([
83
            'shortname' => str_repeat("S", \core_course\constants::SHORTNAME_MAXIMUM_LENGTH),
84
            'fullname' => str_repeat("F", \core_course\constants::FULLNAME_MAXIMUM_LENGTH),
85
        ]);
86
 
87
        // Should have nothing in the recycle bin.
88
        $this->assertEquals(0, $DB->count_records('tool_recyclebin_category'));
89
 
90
        delete_course($course, false);
91
 
92
        // Verify the course is now in the recycle bin.
93
        $recyclebin = new \tool_recyclebin\category_bin($course->category);
94
        $this->assertCount(1, $recyclebin->get_items());
95
    }
96
 
1 efrain 97
    /**
98
     * Check that our hook is called when a course is deleted.
99
     */
11 efrain 100
    public function test_pre_course_category_delete_hook(): void {
1 efrain 101
        global $DB;
102
 
103
        // Should have nothing in the recycle bin.
104
        $this->assertEquals(0, $DB->count_records('tool_recyclebin_category'));
105
 
106
        delete_course($this->course, false);
107
 
108
        // Check the course is now in the recycle bin.
109
        $this->assertEquals(1, $DB->count_records('tool_recyclebin_category'));
110
 
111
        // Now let's delete the course category.
112
        $category = \core_course_category::get($this->course->category);
113
        $category->delete_full(false);
114
 
115
        // Check that the course was deleted from the category recycle bin.
116
        $this->assertEquals(0, $DB->count_records('tool_recyclebin_category'));
117
    }
118
 
119
    /**
120
     * Test that we can restore recycle bin items.
121
     */
11 efrain 122
    public function test_restore(): void {
1 efrain 123
        global $DB;
124
 
125
        delete_course($this->course, false);
126
 
127
        $recyclebin = new \tool_recyclebin\category_bin($this->course->category);
128
        foreach ($recyclebin->get_items() as $item) {
129
            $recyclebin->restore_item($item);
130
        }
131
 
132
        // Check that it was restored and removed from the recycle bin.
133
        $this->assertEquals(2, $DB->count_records('course')); // Site course and the course we restored.
134
        $this->assertEquals(0, count($recyclebin->get_items()));
135
    }
136
 
137
    /**
138
     * Test that we can delete recycle bin items.
139
     */
11 efrain 140
    public function test_delete(): void {
1 efrain 141
        global $DB;
142
 
143
        delete_course($this->course, false);
144
 
145
        $recyclebin = new \tool_recyclebin\category_bin($this->course->category);
146
        foreach ($recyclebin->get_items() as $item) {
147
            $recyclebin->delete_item($item);
148
        }
149
 
150
        // Item was deleted, so no course was restored.
151
        $this->assertEquals(1, $DB->count_records('course')); // Just the site course.
152
        $this->assertEquals(0, count($recyclebin->get_items()));
153
    }
154
 
155
    /**
156
     * Test the cleanup task.
157
     */
11 efrain 158
    public function test_cleanup_task(): void {
1 efrain 159
        global $DB;
160
 
161
        // Set the expiry to 1 week.
162
        set_config('categorybinexpiry', WEEKSECS, 'tool_recyclebin');
163
 
164
        delete_course($this->course, false);
165
 
166
        $recyclebin = new \tool_recyclebin\category_bin($this->course->category);
167
 
168
        // Set deleted date to the distant past.
169
        foreach ($recyclebin->get_items() as $item) {
170
            $item->timecreated = time() - WEEKSECS;
171
            $DB->update_record('tool_recyclebin_category', $item);
172
        }
173
 
174
        // Create another course to delete.
175
        $course = $this->getDataGenerator()->create_course();
176
        delete_course($course, false);
177
 
178
        // Should now be two courses in the recycle bin.
179
        $this->assertEquals(2, count($recyclebin->get_items()));
180
 
181
        // Execute cleanup task.
182
        $this->expectOutputRegex("/\[tool_recyclebin\] Deleting item '\d+' from the category recycle bin/");
183
        $task = new \tool_recyclebin\task\cleanup_category_bin();
184
        $task->execute();
185
 
186
        // Task should only have deleted the course where we updated the time.
187
        $courses = $recyclebin->get_items();
188
        $this->assertEquals(1, count($courses));
189
        $course = reset($courses);
190
        $this->assertEquals('Test course 2', $course->fullname);
191
    }
192
 
193
    /**
194
     * Provider for test_course_restore_with_userdata() and test_course_restore_without_userdata()
195
     *
196
     * Used to verify that recycle bin is immune to various settings. Provides plugin, name, value for
197
     * direct usage with set_config()
198
     */
1441 ariadna 199
    public static function recycle_bin_settings_provider(): array {
1 efrain 200
        return [
201
            'backup/backup_auto_storage moodle' => [[
202
                (object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 0],
203
            ]],
204
 
205
            'backup/backup_auto_storage external' => [[
206
                (object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 1],
207
                (object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true],
208
            ]],
209
 
210
            'backup/backup_auto_storage mixed' => [[
211
                (object)['plugin' => 'backup', 'name' => 'backup_auto_storage', 'value' => 2],
212
                (object)['plugin' => 'backup', 'name' => 'backup_auto_destination', 'value' => true],
213
            ]],
214
 
215
            'restore/restore_general_users moodle' => [[
216
                (object)['plugin' => 'restore', 'name' => 'restore_general_users', 'value' => 0],
217
                (object)['plugin' => 'restore', 'name' => 'restore_general_groups', 'value' => 0],
218
            ]],
219
        ];
220
    }
221
 
222
    /**
223
     * Tests that user data is restored when course is restored.
224
     *
225
     * @dataProvider recycle_bin_settings_provider
226
     * @param array $settings array of plugin, name, value stdClass().
227
     */
11 efrain 228
    public function test_course_restore_with_userdata($settings): void {
1 efrain 229
        global $DB;
230
 
231
        // Force configuration changes from provider.
232
        foreach ($settings as $setting) {
233
            // Need to create a directory for backup_auto_destination.
234
            if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) {
235
                $setting->value = make_request_directory();
236
            }
237
            set_config($setting->name, $setting->value, $setting->plugin);
238
        }
239
 
240
        // We want user data to be included for this test.
241
        set_config('backup_auto_users', true, 'backup');
242
 
243
        $student = $this->getDataGenerator()->create_and_enrol($this->course, 'student');
244
 
245
        // Delete course.
246
        delete_course($this->course, false);
247
        $this->assertFalse($DB->record_exists('course', ['id' => $this->course->id]));
248
 
249
        // Verify there is now a backup @ cat recycle bin file area.
250
        $recyclebin = new \tool_recyclebin\category_bin($this->course->category);
251
        $this->assertEquals(1, count($recyclebin->get_items()));
252
 
253
        // Restore the recycle bin item.
254
        $recyclebin->restore_item(current($recyclebin->get_items()));
255
 
256
        // Get the new course.
257
        $newcourse = $DB->get_record('course', ['shortname' => $this->course->shortname], '*', MUST_EXIST);
258
 
259
        // Check that it was removed from the recycle bin.
260
        $this->assertEquals(0, count($recyclebin->get_items()));
261
 
262
        // Verify that student DOES continue enrolled.
263
        $this->assertTrue(is_enrolled(\context_course::instance($newcourse->id), $student->id));
264
    }
265
 
266
    /**
267
     * Tests that user data is not restored when course is restored.
268
     *
269
     * @dataProvider recycle_bin_settings_provider
270
     * @param array $settings array of plugin, name, value stdClass().
271
     */
11 efrain 272
    public function test_course_restore_without_userdata($settings): void {
1 efrain 273
        global $DB;
274
 
275
        // Force configuration changes from provider.
276
        foreach ($settings as $setting) {
277
            // Need to create a directory for backup_auto_destination.
278
            if ($setting->plugin === 'backup' && $setting->name === 'backup_auto_destination' && $setting->value === true) {
279
                $setting->value = make_request_directory();
280
            }
281
            set_config($setting->name, $setting->value, $setting->plugin);
282
        }
283
 
284
        // We want user data to be included for this test.
285
        set_config('backup_auto_users', false, 'backup');
286
 
287
        $student = $this->getDataGenerator()->create_and_enrol($this->course, 'student');
288
 
289
        // Delete course.
290
        delete_course($this->course, false);
291
        $this->assertFalse($DB->record_exists('course', ['id' => $this->course->id]));
292
 
293
        // Verify there is now a backup @ cat recycle bin file area.
294
        $recyclebin = new \tool_recyclebin\category_bin($this->course->category);
295
        $this->assertEquals(1, count($recyclebin->get_items()));
296
 
297
        // Restore the recycle bin item.
298
        $recyclebin->restore_item(current($recyclebin->get_items()));
299
 
300
        // Get the new course.
301
        $newcourse = $DB->get_record('course', ['shortname' => $this->course->shortname], '*', MUST_EXIST);
302
 
303
        // Check that it was removed from the recycle bin.
304
        $this->assertEquals(0, count($recyclebin->get_items()));
305
 
306
        // Verify that student DOES NOT continue enrolled.
307
        $this->assertFalse(is_enrolled(\context_course::instance($newcourse->id), $student->id));
308
    }
309
}