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
/**
18
 * Unit tests for mod_folder lib
19
 *
20
 * @package    mod_folder
21
 * @category   external
22
 * @copyright  2015 Juan Leyva <juan@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 * @since      Moodle 3.0
25
 */
26
namespace mod_folder;
27
 
28
use context_user;
29
use context_module;
30
 
31
defined('MOODLE_INTERNAL') || die();
32
 
33
 
34
/**
35
 * Unit tests for mod_folder lib
36
 *
37
 * @package    mod_folder
38
 * @category   external
39
 * @copyright  2015 Juan Leyva <juan@moodle.com>
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 * @since      Moodle 3.0
42
 */
1441 ariadna 43
final class lib_test extends \advanced_testcase {
1 efrain 44
 
45
    /**
46
     * Setup.
47
     */
48
    public function setUp(): void {
1441 ariadna 49
        parent::setUp();
1 efrain 50
        $this->resetAfterTest();
51
        $this->setAdminUser();
52
    }
53
 
54
    /**
55
     * Prepares things before this test case is initialised
56
     * @return void
57
     */
58
    public static function setUpBeforeClass(): void {
59
        global $CFG;
60
        require_once($CFG->dirroot . '/mod/folder/lib.php');
1441 ariadna 61
        parent::setUpBeforeClass();
1 efrain 62
    }
63
 
64
    /**
65
     * Test folder_view
66
     * @return void
67
     */
11 efrain 68
    public function test_folder_view(): void {
1 efrain 69
        global $CFG;
70
 
71
        $CFG->enablecompletion = 1;
72
 
73
        // Setup test data.
74
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
75
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id),
76
                                                            array('completion' => 2, 'completionview' => 1));
77
        $context = \context_module::instance($folder->cmid);
78
        $cm = get_coursemodule_from_instance('folder', $folder->id);
79
 
80
        // Trigger and capture the event.
81
        $sink = $this->redirectEvents();
82
 
83
        folder_view($folder, $course, $cm, $context);
84
 
85
        $events = $sink->get_events();
86
        // 2 additional events thanks to completion.
87
        $this->assertCount(3, $events);
88
        $event = array_shift($events);
89
 
90
        // Checking that the event contains the expected values.
91
        $this->assertInstanceOf('\mod_folder\event\course_module_viewed', $event);
92
        $this->assertEquals($context, $event->get_context());
93
        $moodleurl = new \moodle_url('/mod/folder/view.php', array('id' => $cm->id));
94
        $this->assertEquals($moodleurl, $event->get_url());
95
        $this->assertEventContextNotUsed($event);
96
        $this->assertNotEmpty($event->get_name());
97
 
98
        // Check completion status.
99
        $completion = new \completion_info($course);
100
        $completiondata = $completion->get_data($cm);
101
        $this->assertEquals(1, $completiondata->completionstate);
102
    }
103
 
11 efrain 104
    public function test_folder_core_calendar_provide_event_action(): void {
1 efrain 105
        // Create the activity.
106
        $course = $this->getDataGenerator()->create_course();
107
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
108
 
109
        // Create a calendar event.
110
        $event = $this->create_action_event($course->id, $folder->id,
111
            \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
112
 
113
        // Create an action factory.
114
        $factory = new \core_calendar\action_factory();
115
 
116
        // Decorate action event.
117
        $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory);
118
 
119
        // Confirm the event was decorated.
120
        $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
121
        $this->assertEquals(get_string('view'), $actionevent->get_name());
122
        $this->assertInstanceOf('moodle_url', $actionevent->get_url());
123
        $this->assertEquals(1, $actionevent->get_item_count());
124
        $this->assertTrue($actionevent->is_actionable());
125
    }
126
 
11 efrain 127
    public function test_folder_core_calendar_provide_event_action_for_non_user(): void {
1 efrain 128
        global $CFG;
129
 
130
        // Create a course.
131
        $course = $this->getDataGenerator()->create_course();
132
 
133
        // Create the activity.
134
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
135
 
136
        // Create a calendar event.
137
        $event = $this->create_action_event($course->id, $folder->id,
138
                \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
139
 
140
        // Now, log out.
141
        $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
142
        $this->setUser();
143
 
144
        // Create an action factory.
145
        $factory = new \core_calendar\action_factory();
146
 
147
        // Decorate action event.
148
        $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory);
149
 
150
        // Confirm the event is not shown at all.
151
        $this->assertNull($actionevent);
152
    }
153
 
11 efrain 154
    public function test_folder_core_calendar_provide_event_action_in_hidden_section(): void {
1 efrain 155
        // Create a course.
156
        $course = $this->getDataGenerator()->create_course();
157
 
158
        // Create a student.
159
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
160
 
161
        // Create the activity.
162
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
163
 
164
        // Create a calendar event.
165
        $event = $this->create_action_event($course->id, $folder->id,
166
                \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
167
 
168
        // Set sections 0 as hidden.
169
        set_section_visible($course->id, 0, 0);
170
 
171
        // Create an action factory.
172
        $factory = new \core_calendar\action_factory();
173
 
174
        // Decorate action event.
175
        $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id);
176
 
177
        // Confirm the event is not shown at all.
178
        $this->assertNull($actionevent);
179
    }
180
 
11 efrain 181
    public function test_folder_core_calendar_provide_event_action_for_user(): void {
1 efrain 182
        // Create a course.
183
        $course = $this->getDataGenerator()->create_course();
184
 
185
        // Create a student.
186
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
187
 
188
        // Create the activity.
189
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
190
 
191
        // Create a calendar event.
192
        $event = $this->create_action_event($course->id, $folder->id,
193
                \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
194
 
195
        // Now, log out.
196
        $this->setUser();
197
 
198
        // Create an action factory.
199
        $factory = new \core_calendar\action_factory();
200
 
201
        // Decorate action event for the student.
202
        $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id);
203
 
204
        // Confirm the event was decorated.
205
        $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
206
        $this->assertEquals(get_string('view'), $actionevent->get_name());
207
        $this->assertInstanceOf('moodle_url', $actionevent->get_url());
208
        $this->assertEquals(1, $actionevent->get_item_count());
209
        $this->assertTrue($actionevent->is_actionable());
210
    }
211
 
11 efrain 212
    public function test_folder_core_calendar_provide_event_action_already_completed(): void {
1 efrain 213
        global $CFG;
214
 
215
        $CFG->enablecompletion = 1;
216
 
217
        // Create the activity.
218
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
219
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id),
220
            array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
221
 
222
        // Get some additional data.
223
        $cm = get_coursemodule_from_instance('folder', $folder->id);
224
 
225
        // Create a calendar event.
226
        $event = $this->create_action_event($course->id, $folder->id,
227
            \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
228
 
229
        // Mark the activity as completed.
230
        $completion = new \completion_info($course);
231
        $completion->set_module_viewed($cm);
232
 
233
        // Create an action factory.
234
        $factory = new \core_calendar\action_factory();
235
 
236
        // Decorate action event.
237
        $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory);
238
 
239
        // Ensure result was null.
240
        $this->assertNull($actionevent);
241
    }
242
 
11 efrain 243
    public function test_folder_core_calendar_provide_event_action_already_completed_for_user(): void {
1 efrain 244
        global $CFG;
245
 
246
        $CFG->enablecompletion = 1;
247
 
248
        // Create a course.
249
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
250
 
251
        // Create a student.
252
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
253
 
254
        // Create the activity.
255
        $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id),
256
                array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
257
 
258
        // Get some additional data.
259
        $cm = get_coursemodule_from_instance('folder', $folder->id);
260
 
261
        // Create a calendar event.
262
        $event = $this->create_action_event($course->id, $folder->id,
263
                \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
264
 
265
        // Mark the activity as completed for the student.
266
        $completion = new \completion_info($course);
267
        $completion->set_module_viewed($cm, $student->id);
268
 
269
        // Now, log out.
270
        $this->setUser();
271
 
272
        // Create an action factory.
273
        $factory = new \core_calendar\action_factory();
274
 
275
        // Decorate action event for the student.
276
        $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id);
277
 
278
        // Ensure result was null.
279
        $this->assertNull($actionevent);
280
    }
281
 
282
    /**
283
     * Creates an action event.
284
     *
285
     * @param int $courseid The course id.
286
     * @param int $instanceid The instance id.
287
     * @param string $eventtype The event type.
288
     * @return bool|calendar_event
289
     */
290
    private function create_action_event($courseid, $instanceid, $eventtype) {
291
        $event = new \stdClass();
292
        $event->name = 'Calendar event';
293
        $event->modulename  = 'folder';
294
        $event->courseid = $courseid;
295
        $event->instance = $instanceid;
296
        $event->type = CALENDAR_EVENT_TYPE_ACTION;
297
        $event->eventtype = $eventtype;
298
        $event->timestart = time();
299
 
300
        return \calendar_event::create($event);
301
    }
302
 
303
    /**
304
     * Test Get recent mod activity method.
305
     * @covers ::folder_get_recent_mod_activity
306
     * @dataProvider folder_get_recent_mod_activity_provider
307
     *
308
     * @param int $forcedownload The forcedownload option.
309
     * @param bool $hascapability if the user has the mod/folder:view capability
310
     * @param int $count The expected recent activities entries.
311
     */
11 efrain 312
    public function test_folder_get_recent_mod_activity(int $forcedownload, bool $hascapability, int $count): void {
1 efrain 313
        global $USER, $DB;
314
 
315
        $this->resetAfterTest();
316
        $this->setAdminUser();
317
 
318
        $course = $this->getDataGenerator()->create_course();
319
 
320
        // Add files to draft area.
321
        $filesitem = file_get_unused_draft_itemid();
322
        $usercontext = context_user::instance($USER->id);
323
        $filerecord = [
324
            'component' => 'user',
325
            'filearea' => 'draft',
326
            'contextid' => $usercontext->id,
327
            'itemid' => $filesitem,
328
            'filename' => 'file1.txt', 'filepath' => '/',
329
        ];
330
        $fs = get_file_storage();
331
        $fs->create_file_from_string($filerecord, 'First test file contents');
332
        // And a second file.
333
        $filerecord['filename'] = 'file2.txt';
334
        $fs->create_file_from_string($filerecord, 'Second test file contents');
335
 
336
        // Create the activity.
337
        $module = $this->getDataGenerator()->create_module(
338
            'folder',
339
            ['course' => $course->id, 'forcedownload' => $forcedownload, 'files' => $filesitem]
340
        );
341
 
342
        // Get some additional data.
343
        $cm = get_coursemodule_from_instance('folder', $module->id);
344
        $context = context_module::instance($cm->id);
345
 
346
        // Add user with the specific capability.
347
        $user = $this->getDataGenerator()->create_user();
348
        $this->getDataGenerator()->enrol_user($user->id, $course->id, 'editingteacher');
349
        if (!$hascapability) {
350
            // The recent activiy uses "folder:view" capability which is allowed by default.
351
            $role = $DB->get_record('role', ['shortname' => 'editingteacher'], '*', MUST_EXIST);
352
            assign_capability('mod/folder:view', CAP_PROHIBIT, $role->id, $context->id, true);
353
        }
354
        $this->setUser($user);
355
 
356
        // Get the recent activity.
357
        $index = 1;
358
        $activities = [];
359
        folder_get_recent_mod_activity($activities, $index, time() - HOURSECS, $course->id, $cm->id);
360
 
361
        // Check recent activity.
362
        $this->assertCount($count, $activities);
363
        foreach ($activities as $index => $activity) {
364
            $this->assertEquals('folder', $activity->type);
365
            $content = $activity->content;
366
            $this->assertEquals("file{$index}.txt", $content->filename);
367
            $urlparams = $content->url->params();
368
            if ($forcedownload) {
369
                $this->assertEquals(1, $urlparams['forcedownload']);
370
            } else {
371
                $this->assertArrayNotHasKey('forcedownload', $urlparams);
372
            }
373
        }
374
    }
375
 
376
    /**
377
     * Data provider for test_folder_get_recent_mod_activity().
378
     *
379
     * @return array
380
     */
1441 ariadna 381
    public static function folder_get_recent_mod_activity_provider(): array {
1 efrain 382
        return [
383
            'Teacher with force download' => [
384
                'forcedownload' => 1,
385
                'hascapability' => true,
386
                'count' => 2,
387
            ],
388
            'Teacher with no force download' => [
389
                'forcedownload' => 0,
390
                'hascapability' => true,
391
                'count' => 2,
392
            ],
393
            'Invalid user with force download' => [
394
                'forcedownload' => 1,
395
                'hascapability' => false,
396
                'count' => 0,
397
            ],
398
            'Invalid user with no force download' => [
399
                'forcedownload' => 0,
400
                'hascapability' => false,
401
                'count' => 0,
402
            ],
403
        ];
404
    }
405
}