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
namespace mod_h5pactivity;
19
 
20
use advanced_testcase;
21
use mod_h5pactivity\local\manager;
22
 
23
/**
24
 * Unit tests for (some of) mod/h5pactivity/lib.php.
25
 *
26
 * @package    mod_h5pactivity
27
 * @copyright  2021 Ilya Tregubov <ilya@moodle.com>
28
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29
 */
11 efrain 30
final class lib_test extends advanced_testcase {
1 efrain 31
 
32
    /**
33
     * Load required test libraries
34
     */
35
    public static function setUpBeforeClass(): void {
36
        global $CFG;
37
        require_once("{$CFG->dirroot}/mod/h5pactivity/lib.php");
38
    }
39
 
40
    /**
41
     * Test that h5pactivity_delete_instance removes data.
42
     *
43
     * @covers ::h5pactivity_delete_instance
44
     */
11 efrain 45
    public function test_h5pactivity_delete_instance(): void {
1 efrain 46
        global $DB;
47
        $this->resetAfterTest();
48
        $this->setAdminUser();
49
 
50
        $course = $this->getDataGenerator()->create_course();
51
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
52
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
53
        $this->setUser($user);
54
 
55
        /** @var \mod_h5pactivity_generator $generator */
56
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
57
 
58
        /** @var \core_h5p_generator $h5pgenerator */
59
        $h5pgenerator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
60
 
61
        // Add an attempt to the H5P activity.
62
        $attemptinfo = [
63
            'userid' => $user->id,
64
            'h5pactivityid' => $activity->id,
65
            'attempt' => 1,
66
            'interactiontype' => 'compound',
67
            'rawscore' => 2,
68
            'maxscore' => 2,
69
            'duration' => 1,
70
            'completion' => 1,
71
            'success' => 0,
72
        ];
73
        $generator->create_attempt($attemptinfo);
74
 
75
        // Add also a xAPI state to the H5P activity.
76
        $filerecord = [
77
            'contextid' => \context_module::instance($activity->cmid)->id,
78
            'component' => 'mod_h5pactivity',
79
            'filearea' => 'package',
80
            'itemid' => 0,
81
            'filepath' => '/',
82
            'filename' => 'dummy.h5p',
83
            'addxapistate' => true,
84
        ];
85
        $h5pgenerator->generate_h5p_data(false, $filerecord);
86
 
87
        // Check the H5P activity exists and the attempt has been created.
88
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
89
        $this->assertEquals(2, $DB->count_records('grade_items'));
90
        $this->assertEquals(2, $DB->count_records('grade_grades'));
91
        $this->assertEquals(1, $DB->count_records('xapi_states'));
92
 
93
        // Check nothing happens when given activity id doesn't exist.
94
        h5pactivity_delete_instance($activity->id + 1);
95
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
96
        $this->assertEquals(2, $DB->count_records('grade_items'));
97
        $this->assertEquals(2, $DB->count_records('grade_grades'));
98
        $this->assertEquals(1, $DB->count_records('xapi_states'));
99
 
100
        // Check the H5P instance and its associated data is removed.
101
        h5pactivity_delete_instance($activity->id);
102
        $this->assertEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
103
        $this->assertEquals(1, $DB->count_records('grade_items'));
104
        $this->assertEquals(1, $DB->count_records('grade_grades'));
105
        $this->assertEquals(0, $DB->count_records('xapi_states'));
106
    }
107
 
108
    /**
109
     * Test that assign_print_recent_activity shows ungraded submitted assignments.
110
     *
111
     * @covers ::h5pactivity_print_recent_activity
112
     */
11 efrain 113
    public function test_print_recent_activity(): void {
1 efrain 114
        $this->resetAfterTest();
115
        $this->setAdminUser();
116
 
117
        $course = $this->getDataGenerator()->create_course();
118
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
119
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
120
            ['course' => $course, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT]);
121
 
122
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
123
 
124
        $manager = manager::create_from_instance($activity);
125
        $cm = $manager->get_coursemodule();
126
 
127
        $user = $student;
128
        $params = ['cmid' => $cm->id, 'userid' => $user->id];
129
        $generator->create_content($activity, $params);
130
        $this->setUser($student);
131
        $this->expectOutputRegex('/submitted:/');
132
        h5pactivity_print_recent_activity($course, true, time() - 3600);
133
    }
134
 
135
    /**
136
     * Test that h5pactivity_print_recent_activity does not display any warnings when a custom fullname has been configured.
137
     *
138
     * @covers ::h5pactivity_print_recent_activity
139
     */
11 efrain 140
    public function test_print_recent_activity_fullname(): void {
1 efrain 141
        $this->resetAfterTest();
142
        $this->setAdminUser();
143
 
144
        $course = $this->getDataGenerator()->create_course();
145
        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
146
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
147
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
148
            ['course' => $course, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT]);
149
 
150
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
151
 
152
        $manager = manager::create_from_instance($activity);
153
        $cm = $manager->get_coursemodule();
154
 
155
        $user = $student;
156
        $params = ['cmid' => $cm->id, 'userid' => $user->id];
157
        $generator->create_content($activity, $params);
158
 
159
        $this->setUser($teacher);
160
 
161
        $this->expectOutputRegex('/submitted:/');
162
        set_config('fullnamedisplay', 'firstname, lastnamephonetic');
163
        h5pactivity_print_recent_activity($course, false, time() - 3600);
164
    }
165
 
166
    /**
167
     * Test that h5pactivity_get_recent_mod_activity fetches the h5pactivity correctly.
168
     *
169
     * @covers ::h5pactivity_get_recent_mod_activity
170
     */
11 efrain 171
    public function test_h5pactivity_get_recent_mod_activity(): void {
1 efrain 172
        $this->resetAfterTest();
173
        $this->setAdminUser();
174
 
175
        $course = $this->getDataGenerator()->create_course();
176
        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
177
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
178
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
179
            ['course' => $course, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT]);
180
 
181
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
182
 
183
        $manager = manager::create_from_instance($activity);
184
        $cm = $manager->get_coursemodule();
185
 
186
        $user = $student;
187
        $params = ['cmid' => $cm->id, 'userid' => $user->id];
188
        $generator->create_content($activity, $params);
189
 
190
        $index = 1;
191
        $activities = [
192
            $index => (object) [
193
                'type' => 'h5pactivity',
194
                'cmid' => $cm->id,
195
            ],
196
        ];
197
 
198
        $this->setUser($teacher);
199
        h5pactivity_get_recent_mod_activity($activities, $index, time() - HOURSECS, $course->id, $cm->id);
200
 
201
        $activity = $activities[1];
202
        $this->assertEquals("h5pactivity", $activity->type);
203
        $this->assertEquals($student->id, $activity->user->id);
204
    }
205
 
206
    /**
207
     * Test that h5pactivity_get_recent_mod_activity fetches activity correctly.
208
     *
209
     * @covers ::h5pactivity_fetch_recent_activity
210
     */
11 efrain 211
    public function test_h5pactivity_fetch_recent_activity(): void {
1 efrain 212
        global $DB;
213
 
214
        $this->resetAfterTest();
215
        $this->setAdminUser();
216
 
217
        $course = $this->getDataGenerator()->create_course();
218
 
219
        // Create users and groups.
220
        $students = array();
221
        $groups = array();
222
        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
223
 
224
        for ($i = 1; $i < 6; $i++) {
225
            $students[$i] = $this->getDataGenerator()->create_and_enrol($course, 'student');
226
            $groups[$i] = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
227
        }
228
        $groups[$i] = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'participation' => 0));
229
 
230
        // Update the course set the groupmode SEPARATEGROUPS and forced.
231
        update_course((object)array('id' => $course->id, 'groupmode' => SEPARATEGROUPS, 'groupmodeforce' => true));
232
 
233
        // Student 1 is in groups 1 and 3.
234
        groups_add_member($groups[1], $students[1]);
235
        groups_add_member($groups[3], $students[1]);
236
 
237
        // Student 2 is in groups 1 and 2.
238
        groups_add_member($groups[1], $students[2]);
239
        groups_add_member($groups[2], $students[2]);
240
 
241
        // Student 3 is only in group 3.
242
        groups_add_member($groups[3], $students[3]);
243
 
244
        // Student 4 is only in group 5 (non-participation).
245
        groups_add_member($groups[6], $students[4]);
246
 
247
        // Student 5 is not in any groups.
248
 
249
        // Grader is only in group 3.
250
        groups_add_member($groups[3], $teacher);
251
 
252
        $timestart = time() - 1;
253
        // Create h5pactivity.
254
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
255
            ['course' => $course->id, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT,
256
                'groupmode' => SEPARATEGROUPS]);
257
 
258
        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
259
        $cmcontext = \context_module::instance($activity->cmid);
260
        assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $teacherrole->id, $cmcontext, true);
261
 
262
        $manager = manager::create_from_instance($activity);
263
        $cm = $manager->get_coursemodule();
264
 
265
        // Create attempts.
266
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
267
        foreach ($students as $student) {
268
            $params = ['cmid' => $cm->id, 'userid' => $student->id];
269
            $generator->create_content($activity, $params);
270
        }
271
 
272
        // Get all attempts.
273
        $dbparams = [$timestart, $course->id, 'h5pactivity'];
274
        $userfieldsapi = \core_user\fields::for_userpic();
275
        $namefields = $userfieldsapi->get_sql('u', false, '', 'userid', false)->selects;;
276
 
277
        $sql = "SELECT h5pa.id, h5pa.timemodified, cm.id as cmid, $namefields
278
                  FROM {h5pactivity_attempts} h5pa
279
                  JOIN {h5pactivity} h5p      ON h5p.id = h5pa.h5pactivityid
280
                  JOIN {course_modules} cm ON cm.instance = h5p.id
281
                  JOIN {modules} md        ON md.id = cm.module
282
                  JOIN {user} u            ON u.id = h5pa.userid
283
                 WHERE h5pa.timemodified > ?
284
                   AND h5p.course = ?
285
                   AND md.name = ?
286
              ORDER BY h5pa.timemodified ASC";
287
 
288
        $submissions = $DB->get_records_sql($sql, $dbparams);
289
        $this->assertCount(count($students), $submissions);
290
 
291
        // Fetch activity for student (only his own).
292
        $this->setUser($students[1]);
293
        $recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
294
        $this->assertCount(1, $recentactivity);
295
        $this->assertEquals($students[1]->id, $recentactivity[$students[1]->id]->userid);
296
 
297
        // Fetch users group info for grader.
298
        $this->setUser($teacher);
299
        $recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
300
        $this->assertCount(2, $recentactivity);
301
        // Grader, Student 1 and 3 are in Group 3.
302
        $this->assertEquals($students[1]->id, $recentactivity[$students[1]->id]->userid);
303
        $this->assertEquals($students[3]->id, $recentactivity[$students[3]->id]->userid);
304
 
305
        // Grader is in Group 2.
306
        groups_remove_member($groups[3], $teacher);
307
        groups_add_member($groups[2], $teacher);
308
        get_fast_modinfo($course->id, 0, true);
309
        $recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
310
        $this->assertCount(1, $recentactivity);
311
        // Grader, Student 2 are in Group 2.
312
        $this->assertEquals($students[2]->id, $recentactivity[$students[2]->id]->userid);
313
 
314
        // Grader is in Group 1.
315
        groups_remove_member($groups[2], $teacher);
316
        groups_add_member($groups[1], $teacher);
317
        get_fast_modinfo($course->id, 0, true);
318
        $recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
319
        $this->assertCount(2, $recentactivity);
320
        // Grader, Student 1 and 2 are in Group 1.
321
        $this->assertEquals($students[1]->id, $recentactivity[$students[1]->id]->userid);
322
        $this->assertEquals($students[2]->id, $recentactivity[$students[2]->id]->userid);
323
 
324
        // Grader is in no group.
325
        groups_remove_member($groups[1], $teacher);
326
        get_fast_modinfo($course->id, 0, true);
327
        $recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
328
        // Student 4 and Student 5 have submissions, but they are not in a participation group, so they do not show up in recent
329
        // activity for separate groups mode.
330
        $this->assertCount(0, $recentactivity);
331
    }
332
 
333
    /**
334
     * Test that h5pactivity_reset_userdata reset user data.
335
     *
336
     * @covers ::h5pactivity_reset_userdata
337
     */
11 efrain 338
    public function test_h5pactivity_reset_userdata(): void {
1 efrain 339
        global $DB;
340
        $this->resetAfterTest();
341
        $this->setAdminUser();
342
 
343
        $course = $this->getDataGenerator()->create_course();
344
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
345
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
346
        $this->setUser($user);
347
 
348
        /** @var \mod_h5pactivity_generator $generator */
349
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
350
 
351
        /** @var \core_h5p_generator $h5pgenerator */
352
        $h5pgenerator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
353
 
354
        // Add an attempt to the H5P activity.
355
        $attemptinfo = [
356
            'userid' => $user->id,
357
            'h5pactivityid' => $activity->id,
358
            'attempt' => 1,
359
            'interactiontype' => 'compound',
360
            'rawscore' => 2,
361
            'maxscore' => 2,
362
            'duration' => 1,
363
            'completion' => 1,
364
            'success' => 0,
365
        ];
366
        $generator->create_attempt($attemptinfo);
367
 
368
        // Add also a xAPI state to the H5P activity.
369
        $filerecord = [
370
            'contextid' => \context_module::instance($activity->cmid)->id,
371
            'component' => 'mod_h5pactivity',
372
            'filearea' => 'package',
373
            'itemid' => 0,
374
            'filepath' => '/',
375
            'filename' => 'dummy.h5p',
376
            'addxapistate' => true,
377
        ];
378
        $h5pgenerator->generate_h5p_data(false, $filerecord);
379
 
380
        // Check the H5P activity exists and the attempt has been created with the expected data.
381
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
382
        $this->assertEquals(2, $DB->count_records('grade_items'));
383
        $this->assertEquals(2, $DB->count_records('grade_grades'));
384
        $this->assertEquals(1, $DB->count_records('xapi_states'));
385
 
386
        // Check nothing happens when reset_h5pactivity is not set.
387
        $data = new \stdClass();
388
        h5pactivity_reset_userdata($data);
389
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
390
        $this->assertEquals(2, $DB->count_records('grade_items'));
391
        $this->assertEquals(2, $DB->count_records('grade_grades'));
392
        $this->assertEquals(1, $DB->count_records('xapi_states'));
393
        $this->assertEquals(1, $DB->count_records('xapi_states'));
394
 
395
        // Check nothing happens when reset_h5pactivity is not set.
396
        $data = (object) [
397
            'courseid' => $course->id,
398
        ];
399
        h5pactivity_reset_userdata($data);
400
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
401
        $this->assertEquals(2, $DB->count_records('grade_items'));
402
        $this->assertEquals(2, $DB->count_records('grade_grades'));
403
        $this->assertEquals(1, $DB->count_records('xapi_states'));
404
        $this->assertEquals(1, $DB->count_records('xapi_states'));
405
 
406
        // Check nothing happens when the given course doesn't exist.
407
        $data = (object) [
408
            'reset_h5pactivity' => true,
409
            'courseid' => $course->id + 1,
410
        ];
411
        h5pactivity_reset_userdata($data);
412
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
413
        $this->assertEquals(2, $DB->count_records('grade_items'));
414
        $this->assertEquals(2, $DB->count_records('grade_grades'));
415
        $this->assertEquals(1, $DB->count_records('xapi_states'));
416
        $this->assertEquals(1, $DB->count_records('xapi_states'));
417
 
418
        // Check the H5P instance and its associated data is reset.
419
        $data = (object) [
420
            'reset_h5pactivity' => true,
421
            'courseid' => $course->id,
422
        ];
423
        h5pactivity_reset_userdata($data);
424
        $this->assertNotEmpty($DB->get_record('h5pactivity', ['id' => $activity->id]));
425
        $this->assertEquals(2, $DB->count_records('grade_items'));
426
        $this->assertEquals(1, $DB->count_records('grade_grades'));
427
        $this->assertEquals(0, $DB->count_records('xapi_states'));
428
    }
429
}