Proyectos de Subversion Moodle

Rev

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