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\local;
19
use context_module;
20
use stdClass;
21
 
22
/**
23
 * Manager tests class for mod_h5pactivity.
24
 *
25
 * @package    mod_h5pactivity
26
 * @covers     \mod_h5pactivity\local\manager
27
 * @category   test
28
 * @copyright  2020 Ferran Recio <ferran@moodle.com>
29
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 */
31
class manager_test extends \advanced_testcase {
32
 
33
    /**
34
     * Test for static create methods.
35
     */
11 efrain 36
    public function test_create(): void {
1 efrain 37
 
38
        $this->resetAfterTest();
39
        $this->setAdminUser();
40
 
41
        $course = $this->getDataGenerator()->create_course();
42
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
43
        $cm = get_coursemodule_from_id('h5pactivity', $activity->cmid, 0, false, MUST_EXIST);
44
        $context = context_module::instance($cm->id);
45
 
46
        $manager = manager::create_from_instance($activity);
47
        $manageractivity = $manager->get_instance();
48
        $this->assertEquals($activity->id, $manageractivity->id);
49
        $managercm = $manager->get_coursemodule();
50
        $this->assertEquals($cm->id, $managercm->id);
51
        $managercontext = $manager->get_context();
52
        $this->assertEquals($context->id, $managercontext->id);
53
 
54
        $manager = manager::create_from_coursemodule($cm);
55
        $manageractivity = $manager->get_instance();
56
        $this->assertEquals($activity->id, $manageractivity->id);
57
        $managercm = $manager->get_coursemodule();
58
        $this->assertEquals($cm->id, $managercm->id);
59
        $managercontext = $manager->get_context();
60
        $this->assertEquals($context->id, $managercontext->id);
61
    }
62
 
63
    /**
64
     * Test for is_tracking_enabled and can_submit methods.
65
     *
66
     * @covers ::is_tracking_enabled
67
     * @covers ::can_submit
68
     * @dataProvider is_tracking_enabled_data
69
     * @param bool $login if the user is logged in
70
     * @param string $role user role in course
71
     * @param int $enabletracking if tracking is enabled
72
     * @param bool $expectedtracking expected result for is_tracking_enabled()
73
     * @param bool $expectedsubmit expected result for can_submit()
74
     */
75
    public function test_is_tracking_enabled_and_can_submit(bool $login, string $role, int $enabletracking, bool $expectedtracking,
76
            bool $expectedsubmit): void {
77
 
78
        $this->resetAfterTest();
79
        $this->setAdminUser();
80
 
81
        $course = $this->getDataGenerator()->create_course();
82
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
83
                ['course' => $course, 'enabletracking' => $enabletracking]);
84
 
85
        $user = $this->getDataGenerator()->create_and_enrol($course, $role);
86
        if ($login) {
87
            $this->setUser($user);
88
            $param = null;
89
        } else {
90
            $param = $user;
91
        }
92
 
93
        $manager = manager::create_from_instance($activity);
94
        $this->assertEquals($expectedtracking, $manager->is_tracking_enabled());
95
        $this->assertEquals($expectedsubmit, $manager->can_submit($param));
96
    }
97
 
98
    /**
99
     * Data provider for test_is_tracking_enabled_and_can_submit.
100
     *
101
     * @return array
102
     */
103
    public function is_tracking_enabled_data(): array {
104
        return [
105
            'Logged student, tracking enabled' => [
106
                true, 'student', 1, true, true,
107
            ],
108
            'Logged student, tracking disabled' => [
109
                true, 'student', 0, false, true,
110
            ],
111
            'Logged teacher, tracking enabled' => [
112
                true, 'editingteacher', 1, true, false,
113
            ],
114
            'Logged teacher, tracking disabled' => [
115
                true, 'editingteacher', 0, false, false,
116
            ],
117
            'No logged student, tracking enabled' => [
118
                true, 'student', 1, true, true,
119
            ],
120
            'No logged student, tracking disabled' => [
121
                true, 'student', 0, false, true,
122
            ],
123
            'No logged teacher, tracking enabled' => [
124
                true, 'editingteacher', 1, true, false,
125
            ],
126
            'No logged teacher, tracking disabled' => [
127
                true, 'editingteacher', 0, false, false,
128
            ],
129
        ];
130
    }
131
 
132
    /**
133
     * Test for get_users_scaled_score.
134
     *
135
     * @dataProvider get_users_scaled_score_data
136
     * @param int $enabletracking if tracking is enabled
137
     * @param int $gradingmethod new grading method
138
     * @param array $result1 student 1 results (scaled, timemodified, attempt number)
139
     * @param array $result2 student 2 results (scaled, timemodified, attempt number)
140
     */
11 efrain 141
    public function test_get_users_scaled_score(int $enabletracking, int $gradingmethod, array $result1, array $result2): void {
1 efrain 142
        global $DB;
143
 
144
        $this->resetAfterTest();
145
        $this->setAdminUser();
146
 
147
        $course = $this->getDataGenerator()->create_course();
148
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
149
                ['course' => $course, 'enabletracking' => $enabletracking, 'grademethod' => $gradingmethod]);
150
 
151
        // Generate two users with 4 attempts each.
152
        $user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
153
        $this->generate_fake_attempts($activity, $user1, 1);
154
        $user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
155
        $this->generate_fake_attempts($activity, $user2, 2);
156
 
157
        $manager = manager::create_from_instance($activity);
158
 
159
        // Get all users scaled scores.
160
        $scaleds = $manager->get_users_scaled_score();
161
 
162
        // No results will be returned if tracking is dsabled or manual grading method is defined.
163
        if (empty($result1)) {
164
            $this->assertNull($scaleds);
165
            return;
166
        }
167
 
168
        $this->assertCount(2, $scaleds);
169
 
170
        // Check expected user1 scaled score.
171
        $scaled = $scaleds[$user1->id];
172
        $this->assertEquals($user1->id, $scaled->userid);
173
        $this->assertEquals($result1[0], $scaled->scaled);
174
        $this->assertEquals($result1[1], $scaled->timemodified);
175
        if ($result1[2]) {
176
            $attempt = $DB->get_record('h5pactivity_attempts', ['id' => $scaled->attemptid]);
177
            $this->assertEquals($attempt->h5pactivityid, $activity->id);
178
            $this->assertEquals($attempt->userid, $scaled->userid);
179
            $this->assertEquals($attempt->scaled, round($scaled->scaled, 5));
180
            $this->assertEquals($attempt->timemodified, $scaled->timemodified);
181
            $this->assertEquals($result1[2], $attempt->attempt);
182
        } else {
183
            $this->assertEquals(0, $scaled->attemptid);
184
        }
185
 
186
        // Check expected user2 scaled score.
187
        $scaled = $scaleds[$user2->id];
188
        $this->assertEquals($user2->id, $scaled->userid);
189
        $this->assertEquals($result2[0], round($scaled->scaled, 5));
190
        $this->assertEquals($result2[1], $scaled->timemodified);
191
        if ($result2[2]) {
192
            $attempt = $DB->get_record('h5pactivity_attempts', ['id' => $scaled->attemptid]);
193
            $this->assertEquals($attempt->h5pactivityid, $activity->id);
194
            $this->assertEquals($attempt->userid, $scaled->userid);
195
            $this->assertEquals($attempt->scaled, $scaled->scaled);
196
            $this->assertEquals($attempt->timemodified, $scaled->timemodified);
197
            $this->assertEquals($result2[2], $attempt->attempt);
198
        } else {
199
            $this->assertEquals(0, $scaled->attemptid);
200
        }
201
 
202
        // Now check a single user record.
203
        $scaleds = $manager->get_users_scaled_score($user2->id);
204
        $this->assertCount(1, $scaleds);
205
        $scaled2 = $scaleds[$user2->id];
206
        $this->assertEquals($scaled->userid, $scaled2->userid);
207
        $this->assertEquals($scaled->scaled, $scaled2->scaled);
208
        $this->assertEquals($scaled->attemptid, $scaled2->attemptid);
209
        $this->assertEquals($scaled->timemodified, $scaled2->timemodified);
210
    }
211
 
212
    /**
213
     * Data provider for get_users_scaled_score.
214
     *
215
     * @return array
216
     */
217
    public function get_users_scaled_score_data(): array {
218
        return [
219
            'Tracking with max attempt method' => [
220
                1, manager::GRADEHIGHESTATTEMPT, [1.00000, 31, 2], [0.66667, 32, 2]
221
            ],
222
            'Tracking with average attempt method' => [
223
                1, manager::GRADEAVERAGEATTEMPT, [0.61111, 51, 0], [0.52222, 52, 0]
224
            ],
225
            'Tracking with last attempt method' => [
226
                1, manager::GRADELASTATTEMPT, [0.33333, 51, 3], [0.40000, 52, 3]
227
            ],
228
            'Tracking with first attempt method' => [
229
                1, manager::GRADEFIRSTATTEMPT, [0.50000, 11, 1], [0.50000, 12, 1]
230
            ],
231
            'Tracking with manual attempt grading' => [
232
                1, manager::GRADEMANUAL, [], []
233
            ],
234
            'No tracking with max attempt method' => [
235
                0, manager::GRADEHIGHESTATTEMPT, [], []
236
            ],
237
            'No tracking with average attempt method' => [
238
                0, manager::GRADEAVERAGEATTEMPT, [], []
239
            ],
240
            'No tracking with last attempt method' => [
241
                0, manager::GRADELASTATTEMPT, [], []
242
            ],
243
            'No tracking with first attempt method' => [
244
                0, manager::GRADEFIRSTATTEMPT, [], []
245
            ],
246
            'No tracking with manual attempt grading' => [
247
                0, manager::GRADEMANUAL, [], []
248
            ],
249
        ];
250
    }
251
 
252
    /**
253
     * Test static get_grading_methods.
254
     */
11 efrain 255
    public function test_get_grading_methods(): void {
1 efrain 256
        $methods = manager::get_grading_methods();
257
        $this->assertCount(5, $methods);
258
        $this->assertNotEmpty($methods[manager::GRADEHIGHESTATTEMPT]);
259
        $this->assertNotEmpty($methods[manager::GRADEAVERAGEATTEMPT]);
260
        $this->assertNotEmpty($methods[manager::GRADELASTATTEMPT]);
261
        $this->assertNotEmpty($methods[manager::GRADEFIRSTATTEMPT]);
262
        $this->assertNotEmpty($methods[manager::GRADEMANUAL]);
263
    }
264
 
265
    /**
266
     * Test static get_selected_attempt.
267
     *
268
     * @dataProvider get_selected_attempt_data
269
     * @param int $enabletracking if tracking is enabled
270
     * @param int $gradingmethod new grading method
271
     * @param int $result the expected result
272
     */
11 efrain 273
    public function test_get_selected_attempt(int $enabletracking, int $gradingmethod, int $result): void {
1 efrain 274
        $this->resetAfterTest();
275
        $this->setAdminUser();
276
 
277
        $course = $this->getDataGenerator()->create_course();
278
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
279
                ['course' => $course, 'enabletracking' => $enabletracking, 'grademethod' => $gradingmethod]);
280
 
281
        $manager = manager::create_from_instance($activity);
282
 
283
        $selected = $manager->get_selected_attempt();
284
 
285
        $this->assertEquals($result, $selected[0]);
286
        $this->assertNotEmpty($selected[1]);
287
    }
288
 
289
    /**
290
     * Data provider for get_users_scaled_score.
291
     *
292
     * @return array
293
     */
294
    public function get_selected_attempt_data(): array {
295
        return [
296
            'Tracking with max attempt method' => [
297
                1, manager::GRADEHIGHESTATTEMPT, manager::GRADEHIGHESTATTEMPT
298
            ],
299
            'Tracking with average attempt method' => [
300
                1, manager::GRADEAVERAGEATTEMPT, manager::GRADEAVERAGEATTEMPT
301
            ],
302
            'Tracking with last attempt method' => [
303
                1, manager::GRADELASTATTEMPT, manager::GRADELASTATTEMPT
304
            ],
305
            'Tracking with first attempt method' => [
306
                1, manager::GRADEFIRSTATTEMPT, manager::GRADEFIRSTATTEMPT
307
            ],
308
            'Tracking with manual attempt grading' => [
309
                1, manager::GRADEMANUAL, manager::GRADEMANUAL
310
            ],
311
            'No tracking with max attempt method' => [
312
                0, manager::GRADEHIGHESTATTEMPT, manager::GRADEMANUAL
313
            ],
314
            'No tracking with average attempt method' => [
315
                0, manager::GRADEAVERAGEATTEMPT, manager::GRADEMANUAL
316
            ],
317
            'No tracking with last attempt method' => [
318
                0, manager::GRADELASTATTEMPT, manager::GRADEMANUAL
319
            ],
320
            'No tracking with first attempt method' => [
321
                0, manager::GRADEFIRSTATTEMPT, manager::GRADEMANUAL
322
            ],
323
            'No tracking with manual attempt grading' => [
324
                0, manager::GRADEMANUAL, manager::GRADEMANUAL
325
            ],
326
        ];
327
    }
328
 
329
    /**
330
     * Test static get_review_modes.
331
     */
11 efrain 332
    public function test_get_review_modes(): void {
1 efrain 333
        $methods = manager::get_review_modes();
334
        $this->assertCount(2, $methods);
335
        $this->assertNotEmpty($methods[manager::REVIEWCOMPLETION]);
336
        $this->assertNotEmpty($methods[manager::REVIEWNONE]);
337
    }
338
 
339
    /**
340
     * Test get_grader method.
341
     */
11 efrain 342
    public function test_get_grader(): void {
1 efrain 343
        $this->resetAfterTest();
344
        $this->setAdminUser();
345
 
346
        $course = $this->getDataGenerator()->create_course();
347
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
348
        $cm = get_coursemodule_from_id('h5pactivity', $activity->cmid, 0, false, MUST_EXIST);
349
        $context = context_module::instance($cm->id);
350
 
351
        $manager = manager::create_from_instance($activity);
352
        $grader = $manager->get_grader();
353
 
354
        $this->assertInstanceOf('mod_h5pactivity\local\grader', $grader);
355
    }
356
 
357
 
358
    /**
359
     * Test static can_view_all_attempts.
360
     *
361
     * @dataProvider can_view_all_attempts_data
362
     * @param int $enabletracking if tracking is enabled
363
     * @param bool $usestudent if test must be done with a user role
364
     * @param bool $useloggedin if test must be done with the loggedin user
365
     * @param bool $result the expected result
366
     */
11 efrain 367
    public function test_can_view_all_attempts(int $enabletracking, bool $usestudent, bool $useloggedin, bool $result): void {
1 efrain 368
        global $USER;
369
 
370
        $this->resetAfterTest();
371
        $this->setAdminUser();
372
 
373
        $course = $this->getDataGenerator()->create_course();
374
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
375
                ['course' => $course, 'enabletracking' => $enabletracking]);
376
 
377
        $manager = manager::create_from_instance($activity);
378
 
379
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
380
        $loggedin = $USER;
381
 
382
        // We want to test what when the method is called to check a different user than $USER.
383
        if (!$usestudent) {
384
            $loggedin = $user;
385
            $user = $USER;
386
        }
387
 
388
        if ($useloggedin) {
389
            $this->setUser($user);
390
            $user = null;
391
        } else {
392
            $this->setUser($loggedin);
393
        }
394
 
395
        $this->assertEquals($result, $manager->can_view_all_attempts($user));
396
    }
397
 
398
    /**
399
     * Data provider for test_can_view_all_attempts.
400
     *
401
     * @return array
402
     */
403
    public function can_view_all_attempts_data(): array {
404
        return [
405
            // No tracking cases.
406
            'No tracking with admin using $USER' => [
407
                0, false, false, false
408
            ],
409
            'No tracking with student using $USER' => [
410
                0, true, false, false
411
            ],
412
            'No tracking with admin loggedin' => [
413
                0, false, true, false
414
            ],
415
            'No tracking with student loggedin' => [
416
                0, true, true, false
417
            ],
418
            // Tracking enabled cases.
419
            'Tracking with admin using $USER' => [
420
                1, false, false, true
421
            ],
422
            'Tracking with student using $USER' => [
423
                1, true, false, false
424
            ],
425
            'Tracking with admin loggedin' => [
426
                1, false, true, true
427
            ],
428
            'Tracking with student loggedin' => [
429
                1, true, true, false
430
            ],
431
        ];
432
    }
433
 
434
    /**
435
     * Test static can_view_own_attempts.
436
     *
437
     * @dataProvider can_view_own_attempts_data
438
     * @param int $enabletracking if tracking is enabled
439
     * @param int $reviewmode the attempt review mode
440
     * @param bool $useloggedin if test must be done with the loggedin user
441
     * @param bool $hasattempts if the student have attempts
442
     * @param bool $result the expected result
443
     */
444
    public function test_can_view_own_attempts(int $enabletracking, int $reviewmode,
11 efrain 445
            bool $useloggedin, bool $hasattempts, bool $result): void {
1 efrain 446
 
447
        $this->resetAfterTest();
448
        $this->setAdminUser();
449
 
450
        $course = $this->getDataGenerator()->create_course();
451
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
452
                ['course' => $course, 'enabletracking' => $enabletracking, 'reviewmode' => $reviewmode]);
453
 
454
        $manager = manager::create_from_instance($activity);
455
 
456
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
457
 
458
        if ($hasattempts) {
459
            $this->generate_fake_attempts($activity, $user, 1);
460
        }
461
 
462
        if ($useloggedin) {
463
            $this->setUser($user);
464
            $user = null;
465
        }
466
 
467
        $this->assertEquals($result, $manager->can_view_own_attempts($user));
468
    }
469
 
470
    /**
471
     * Data provider for test_can_view_own_attempts.
472
     *
473
     * @return array
474
     */
475
    public function can_view_own_attempts_data(): array {
476
        return [
477
            // No tracking cases.
478
            'No tracking, review none, using $USER, without attempts' => [
479
                0, manager::REVIEWNONE, false, false, false
480
            ],
481
            'No tracking, review enabled, using $USER, without attempts' => [
482
                0, manager::REVIEWCOMPLETION, false, false, false
483
            ],
484
            'No tracking, review none, loggedin, without attempts' => [
485
                0, manager::REVIEWNONE, true, false, false
486
            ],
487
            'No tracking, review enabled, loggedin, without attempts' => [
488
                0, manager::REVIEWCOMPLETION, true, false, false
489
            ],
490
            'No tracking, review none, using $USER, with attempts' => [
491
                0, manager::REVIEWNONE, false, true, false
492
            ],
493
            'No tracking, review enabled, using $USER, with attempts' => [
494
                0, manager::REVIEWCOMPLETION, false, true, false
495
            ],
496
            'No tracking, review none, loggedin, with attempts' => [
497
                0, manager::REVIEWNONE, true, true, false
498
            ],
499
            'No tracking, review enabled, loggedin, with attempts' => [
500
                0, manager::REVIEWCOMPLETION, true, true, false
501
            ],
502
            // Tracking enabled cases.
503
            'Tracking enabled, review none, using $USER, without attempts' => [
504
                1, manager::REVIEWNONE, false, false, false
505
            ],
506
            'Tracking enabled, review enabled, using $USER, without attempts' => [
507
                1, manager::REVIEWCOMPLETION, false, false, true
508
            ],
509
            'Tracking enabled, review none, loggedin, without attempts' => [
510
                1, manager::REVIEWNONE, true, false, false
511
            ],
512
            'Tracking enabled, review enabled, loggedin, without attempts' => [
513
                1, manager::REVIEWCOMPLETION, true, false, true
514
            ],
515
            'Tracking enabled, review none, using $USER, with attempts' => [
516
                1, manager::REVIEWNONE, false, true, false
517
            ],
518
            'Tracking enabled, review enabled, using $USER, with attempts' => [
519
                1, manager::REVIEWCOMPLETION, false, true, true
520
            ],
521
            'Tracking enabled, review none, loggedin, with attempts' => [
522
                1, manager::REVIEWNONE, true, true, false
523
            ],
524
            'Tracking enabled, review enabled, loggedin, with attempts' => [
525
                1, manager::REVIEWCOMPLETION, true, true, true
526
            ],
527
        ];
528
    }
529
 
530
    /**
531
     * Test static count_attempts of one user.
532
     */
11 efrain 533
    public function test_count_attempts(): void {
1 efrain 534
 
535
        $this->resetAfterTest();
536
        $this->setAdminUser();
537
 
538
        $course = $this->getDataGenerator()->create_course();
539
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
540
                ['course' => $course]);
541
 
542
        $manager = manager::create_from_instance($activity);
543
 
544
        // User without attempts.
545
        $user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
546
 
547
        // User with 1 attempt.
548
        $user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
549
        $this->generate_fake_attempts($activity, $user2, 1);
550
 
551
        // User with 2 attempts.
552
        $user3 = $this->getDataGenerator()->create_and_enrol($course, 'student');
553
        $this->generate_fake_attempts($activity, $user3, 1);
554
 
555
        // Incomplete user2 and 3 has only 3 attempts completed.
556
        $this->assertEquals(0, $manager->count_attempts($user1->id));
557
        $this->assertEquals(3, $manager->count_attempts($user2->id));
558
        $this->assertEquals(3, $manager->count_attempts($user3->id));
559
    }
560
 
561
    /**
562
     * Test static count_attempts of all active participants.
563
     *
564
     * @dataProvider count_attempts_all_data
565
     * @param bool $canview if the student role has mod_h5pactivity/view capability
566
     * @param bool $cansubmit if the student role has mod_h5pactivity/submit capability
567
     * @param bool $extrarole if an extra role without submit capability is required
568
     * @param int $result the expected result
569
     */
11 efrain 570
    public function test_count_attempts_all(bool $canview, bool $cansubmit, bool $extrarole, int $result): void {
1 efrain 571
        global $DB;
572
 
573
        $this->resetAfterTest();
574
        $this->setAdminUser();
575
 
576
        $course = $this->getDataGenerator()->create_course();
577
        $activity = $this->getDataGenerator()->create_module(
578
            'h5pactivity',
579
            ['course' => $course]
580
        );
581
 
582
        $manager = manager::create_from_instance($activity);
583
 
584
        $roleid = $DB->get_field('role', 'id', ['shortname' => 'student']);
585
 
586
        $newcap = ($canview) ? CAP_ALLOW : CAP_PROHIBIT;
587
        role_change_permission($roleid, $manager->get_context(), 'mod/h5pactivity:view', $newcap);
588
 
589
        $newcap = ($cansubmit) ? CAP_ALLOW : CAP_PROHIBIT;
590
        role_change_permission($roleid, $manager->get_context(), 'mod/h5pactivity:submit', $newcap);
591
 
592
        // Teacher with review capability and attempts (should not be listed).
593
        if ($extrarole) {
594
            $user1 = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
595
            $this->generate_fake_attempts($activity, $user1, 1);
596
        }
597
 
598
        // Student with attempts.
599
        $user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
600
        $this->generate_fake_attempts($activity, $user2, 1);
601
 
602
        // Another student with attempts.
603
        $user3 = $this->getDataGenerator()->create_and_enrol($course, 'student');
604
        $this->generate_fake_attempts($activity, $user3, 1);
605
 
606
        $this->assertEquals($result, $manager->count_attempts());
607
    }
608
 
609
    /**
610
     * Data provider for test_count_attempts_all.
611
     *
612
     * @return array
613
     */
614
    public function count_attempts_all_data(): array {
615
        return [
616
            'Students with both view and submit capability' => [true, true, false, 6],
617
            'Students without view but with submit capability' => [false, true, false, 0],
618
            'Students with view but without submit capability' => [true, false, false, 6],
619
            'Students without both view and submit capability' => [false, false, false, 0],
620
            'Students with both view and submit capability and extra role' => [true, true, true, 6],
621
            'Students without view but with submit capability and extra role' => [false, true, true, 0],
622
            'Students with view but without submit capability and extra role' => [true, false, true, 6],
623
            'Students without both view and submit capability and extra role' => [false, false, true, 0],
624
        ];
625
    }
626
 
627
    /**
628
     * Test static test_get_active_users_join of all active participants.
629
     *
630
     * Most method scenarios are tested in test_count_attempts_all so we only
631
     * need to test the with $allpotentialusers true and false.
632
     *
633
     * @dataProvider get_active_users_join_data
634
     * @param bool $allpotentialusers if the join should return all potential users or only the submitted ones.
635
     * @param int $result the expected result
636
     */
11 efrain 637
    public function test_get_active_users_join(bool $allpotentialusers, int $result): void {
1 efrain 638
        global $DB;
639
 
640
        $this->resetAfterTest();
641
        $this->setAdminUser();
642
 
643
        $course = $this->getDataGenerator()->create_course();
644
        $activity = $this->getDataGenerator()->create_module(
645
            'h5pactivity',
646
            ['course' => $course]
647
        );
648
 
649
        $manager = manager::create_from_instance($activity);
650
 
651
        $user1 = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
652
        $this->generate_fake_attempts($activity, $user1, 1);
653
 
654
        // Student with attempts.
655
        $user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
656
        $this->generate_fake_attempts($activity, $user2, 1);
657
 
658
        // 2 more students without attempts.
659
        $this->getDataGenerator()->create_and_enrol($course, 'student');
660
        $this->getDataGenerator()->create_and_enrol($course, 'student');
661
 
662
        $usersjoin = $manager->get_active_users_join($allpotentialusers);
663
 
664
        // Final SQL.
665
        $num = $DB->count_records_sql(
666
            "SELECT COUNT(DISTINCT u.id)
667
               FROM {user} u $usersjoin->joins
668
              WHERE $usersjoin->wheres",
669
            array_merge($usersjoin->params)
670
        );
671
 
672
        $this->assertEquals($result, $num);
673
    }
674
 
675
    /**
676
     * Data provider for test_get_active_users_join.
677
     *
678
     * @return array
679
     */
680
    public function get_active_users_join_data(): array {
681
        return [
682
            'All potential users' => [
683
                'allpotentialusers' => true,
684
                'result' => 3,
685
            ],
686
            'Users with attempts' => [
687
                'allpotentialusers' => false,
688
                'result' => 1,
689
            ],
690
        ];
691
    }
692
 
693
    /**
694
     * Test active users joins returns appropriate results for groups
695
     */
696
    public function test_get_active_users_join_groupmode(): void {
697
        global $DB;
698
 
699
        $this->resetAfterTest();
700
        $this->setAdminUser();
701
 
702
        $course = $this->getDataGenerator()->create_course(['groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1]);
703
 
704
        // Teacher/user one in group one.
705
        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
706
        $userone = $this->getDataGenerator()->create_and_enrol($course, 'student');
707
 
708
        $groupone = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
709
        $this->getDataGenerator()->create_group_member(['groupid' => $groupone->id, 'userid' => $teacher->id]);
710
        $this->getDataGenerator()->create_group_member(['groupid' => $groupone->id, 'userid' => $userone->id]);
711
 
712
        // User two in group two.
713
        $usertwo = $this->getDataGenerator()->create_and_enrol($course, 'student');
714
 
715
        $grouptwo = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
716
        $this->getDataGenerator()->create_group_member(['groupid' => $grouptwo->id, 'userid' => $usertwo->id]);
717
 
718
        // User three in no group.
719
        $userthree = $this->getDataGenerator()->create_and_enrol($course, 'student');
720
 
721
        // User four in a non-participation group.
722
        $userfour = $this->getDataGenerator()->create_and_enrol($course, 'student');
723
        $groupthree = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'participation' => 0]);
724
        $this->getDataGenerator()->create_group_member(['groupid' => $groupthree->id, 'userid' => $userfour->id]);
725
 
726
        // Editing teacher in no group.
727
        $editingteacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
728
 
729
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
730
        $manager = manager::create_from_instance($activity);
731
 
732
        // Admin user can view all participants (any group and none).
733
        $usersjoin = $manager->get_active_users_join(true, 0);
734
        $users = $DB->get_fieldset_sql("SELECT u.username FROM {user} u {$usersjoin->joins} WHERE {$usersjoin->wheres}",
735
            $usersjoin->params);
736
 
737
        $this->assertEqualsCanonicalizing(
738
                [$userone->username, $usertwo->username, $userthree->username, $userfour->username], $users);
739
 
740
        // Switch to teacher, who cannot view all participants.
741
        $this->setUser($teacher);
742
 
743
        $usersjoin = $manager->get_active_users_join(true, 0);
744
        $users = $DB->get_fieldset_sql("SELECT u.username FROM {user} u {$usersjoin->joins} WHERE {$usersjoin->wheres}",
745
            $usersjoin->params);
746
 
747
        $this->assertEmpty($users);
748
 
749
        // Teacher can view participants inside group.
750
        $usersjoin = $manager->get_active_users_join(true, $groupone->id);
751
        $users = $DB->get_fieldset_sql("SELECT u.username FROM {user} u {$usersjoin->joins} WHERE {$usersjoin->wheres}",
752
            $usersjoin->params);
753
 
754
        $this->assertEqualsCanonicalizing([$userone->username], $users);
755
 
756
        // Switch to editing teacher, who can view all participants.
757
        $this->setUser($editingteacher);
758
 
759
        $usersjoin = $manager->get_active_users_join(true, 0);
760
        $users = $DB->get_fieldset_sql("SELECT u.username FROM {user} u {$usersjoin->joins} WHERE {$usersjoin->wheres}",
761
            $usersjoin->params);
762
 
763
        $this->assertEqualsCanonicalizing(
764
                [$userone->username, $usertwo->username, $userthree->username, $userfour->username], $users);
765
    }
766
 
767
    /**
768
     * Test getting active users join where there are no roles with 'mod/h5pactivity:reviewattempts' capability
769
     */
770
    public function test_get_active_users_join_no_reviewers(): void {
771
        global $DB;
772
 
773
        $this->resetAfterTest();
774
        $this->setAdminUser();
775
 
776
        $course = $this->getDataGenerator()->create_course();
777
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
778
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
779
 
780
        $manager = manager::create_from_instance($activity);
781
 
782
        // By default manager and editingteacher can review attempts, prohibit both.
783
        $rolemanager = $DB->get_field('role', 'id', ['shortname' => 'manager']);
784
        role_change_permission($rolemanager, $manager->get_context(), 'mod/h5pactivity:reviewattempts', CAP_PROHIBIT);
785
 
786
        $roleeditingteacher = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
787
        role_change_permission($roleeditingteacher, $manager->get_context(), 'mod/h5pactivity:reviewattempts', CAP_PROHIBIT);
788
 
789
        // Generate users join SQL to find matching users.
790
        $usersjoin = $manager->get_active_users_join(true);
791
        $usernames = $DB->get_fieldset_sql(
792
            "SELECT u.username
793
               FROM {user} u
794
                    {$usersjoin->joins}
795
              WHERE {$usersjoin->wheres}",
796
            $usersjoin->params
797
        );
798
 
799
        $this->assertEquals([$user->username], $usernames);
800
    }
801
 
802
    /**
803
     * Test static count_attempts.
804
     */
11 efrain 805
    public function test_count_users_attempts(): void {
1 efrain 806
 
807
        $this->resetAfterTest();
808
        $this->setAdminUser();
809
 
810
        $course = $this->getDataGenerator()->create_course();
811
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
812
                ['course' => $course]);
813
 
814
        $manager = manager::create_from_instance($activity);
815
 
816
        // User without attempts.
817
        $user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
818
 
819
        // User with 1 attempt.
820
        $user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
821
        $this->generate_fake_attempts($activity, $user2, 1);
822
 
823
        // User with 2 attempts.
824
        $user3 = $this->getDataGenerator()->create_and_enrol($course, 'student');
825
        $this->generate_fake_attempts($activity, $user3, 1);
826
 
827
        $attempts = $manager->count_users_attempts();
828
        $this->assertArrayNotHasKey($user1->id, $attempts);
829
        $this->assertArrayHasKey($user2->id, $attempts);
830
        $this->assertEquals(4, $attempts[$user2->id]);
831
        $this->assertArrayHasKey($user3->id, $attempts);
832
        $this->assertEquals(4, $attempts[$user3->id]);
833
    }
834
 
835
    /**
836
     * Test static get_report.
837
     *
838
     * @dataProvider get_report_data
839
     * @param int $enabletracking if tracking is enabled
840
     * @param int $reviewmode the attempt review mode
841
     * @param bool $createattempts if the student have attempts
842
     * @param string $role the user role (student or editingteacher)
843
     * @param array $results the expected classname (or null)
844
     */
845
    public function test_get_report(int $enabletracking, int $reviewmode, bool $createattempts,
11 efrain 846
            string $role, array $results): void {
1 efrain 847
 
848
        $this->resetAfterTest();
849
        $this->setAdminUser();
850
 
851
        $course = $this->getDataGenerator()->create_course();
852
        $activity = $this->getDataGenerator()->create_module('h5pactivity',
853
                ['course' => $course, 'enabletracking' => $enabletracking, 'reviewmode' => $reviewmode]);
854
 
855
        $manager = manager::create_from_instance($activity);
856
        $cm = get_coursemodule_from_id('h5pactivity', $activity->cmid, 0, false, MUST_EXIST);
857
 
858
        $users = [
859
            'editingteacher' => $this->getDataGenerator()->create_and_enrol($course, 'editingteacher'),
860
            'student' => $this->getDataGenerator()->create_and_enrol($course, 'student'),
861
            'otheruser' => $this->getDataGenerator()->create_and_enrol($course, 'student'),
862
        ];
863
 
864
        $attempts = [];
865
        if ($createattempts) {
866
            $this->generate_fake_attempts($activity, $users['student'], 1);
867
            $this->generate_fake_attempts($activity, $users['otheruser'], 2);
868
            $attempts['student'] = attempt::last_attempt($users['student'], $cm);
869
            $attempts['otheruser'] = attempt::last_attempt($users['otheruser'], $cm);
870
        }
871
 
872
        $classnamebase = 'mod_h5pactivity\\local\\report\\';
873
 
874
        $attemptid = null;
875
        if (isset($attempts['student'])) {
876
            $attemptid = $attempts['student']->get_id() ?? null;
877
        }
878
        $userid = $users['student']->id;
879
 
880
        // Check reports.
881
        $this->setUser($users[$role]);
882
 
883
        $report = $manager->get_report(null, null);
884
        if ($results[0] === null) {
885
            $this->assertNull($report);
886
        } else {
887
            $this->assertEquals($classnamebase.$results[0], get_class($report));
888
        }
889
 
890
        $report = $manager->get_report($userid, null);
891
        if ($results[1] === null) {
892
            $this->assertNull($report);
893
        } else {
894
            $this->assertEquals($classnamebase.$results[1], get_class($report));
895
        }
896
 
897
        $report = $manager->get_report($userid, $attemptid);
898
        if ($results[2] === null) {
899
            $this->assertNull($report);
900
        } else {
901
            $this->assertEquals($classnamebase.$results[2], get_class($report));
902
        }
903
 
904
        // Check that student cannot access another student reports.
905
        if ($role == 'student') {
906
            $attemptid = null;
907
            if (isset($attempts['otheruser'])) {
908
                $attemptid = $attempts['otheruser']->get_id() ?? null;
909
            }
910
            $userid = $users['otheruser']->id;
911
 
912
            $report = $manager->get_report($userid, null);
913
            $this->assertNull($report);
914
 
915
            $report = $manager->get_report($userid, $attemptid);
916
            $this->assertNull($report);
917
        }
918
    }
919
 
920
    /**
921
     * Data provider for test_get_report.
922
     *
923
     * @return array
924
     */
925
    public function get_report_data(): array {
926
        return [
927
            // No tracking scenarios.
928
            'No tracking, review none, no attempts, teacher' => [
929
                0, manager::REVIEWNONE, false, 'editingteacher', [null, null, null]
930
            ],
931
            'No tracking, review own, no attempts, teacher' => [
932
                0, manager::REVIEWCOMPLETION, false, 'editingteacher', [null, null, null]
933
            ],
934
            'No tracking, review none, no attempts, student' => [
935
                0, manager::REVIEWNONE, false, 'student', [null, null, null]
936
            ],
937
            'No tracking, review own, no attempts, student' => [
938
                0, manager::REVIEWCOMPLETION, false, 'student', [null, null, null]
939
            ],
940
            'No tracking, review none, with attempts, teacher' => [
941
                0, manager::REVIEWNONE, true, 'editingteacher', [null, null, null]
942
            ],
943
            'No tracking, review own, with attempts, teacher' => [
944
                0, manager::REVIEWCOMPLETION, true, 'editingteacher', [null, null, null]
945
            ],
946
            'No tracking, review none, with attempts, student' => [
947
                0, manager::REVIEWNONE, true, 'student', [null, null, null]
948
            ],
949
            'No tracking, review own, with attempts, student' => [
950
                0, manager::REVIEWCOMPLETION, true, 'student', [null, null, null]
951
            ],
952
            // Tracking enabled scenarios.
953
            'Tracking enabled, review none, no attempts, teacher' => [
954
                1, manager::REVIEWNONE, false, 'editingteacher', ['participants', 'attempts', 'attempts']
955
            ],
956
            'Tracking enabled, review own, no attempts, teacher' => [
957
                1, manager::REVIEWCOMPLETION, false, 'editingteacher', ['participants', 'attempts', 'attempts']
958
            ],
959
            'Tracking enabled, review none, no attempts, student' => [
960
                1, manager::REVIEWNONE, false, 'student', [null, null, null]
961
            ],
962
            'Tracking enabled, review own, no attempts, student' => [
963
                1, manager::REVIEWCOMPLETION, false, 'student', ['attempts', 'attempts', 'attempts']
964
            ],
965
            'Tracking enabled, review none, with attempts, teacher' => [
966
                1, manager::REVIEWNONE, true, 'editingteacher', ['participants', 'attempts', 'results']
967
            ],
968
            'Tracking enabled, review own, with attempts, teacher' => [
969
                1, manager::REVIEWCOMPLETION, true, 'editingteacher', ['participants', 'attempts', 'results']
970
            ],
971
            'Tracking enabled, review none, with attempts, student' => [
972
                1, manager::REVIEWNONE, true, 'student', [null, null, null]
973
            ],
974
            'Tracking enabled, review own, with attempts, student' => [
975
                1, manager::REVIEWCOMPLETION, true, 'student', ['attempts', 'attempts', 'results']
976
            ],
977
        ];
978
    }
979
 
980
    /**
981
     * Test teacher access to student reports (get_report) when course groupmode is SEPARATEGROUPS.
982
     * @covers ::get_report()
983
     * @dataProvider get_report_data_groupmode
984
     *
985
     * @param bool $activitygroupmode Course or activity groupmode
986
     */
987
    public function test_get_report_groupmode(bool $activitygroupmode): void {
988
        global $DB;
989
 
990
        $this->resetAfterTest();
991
        $this->setAdminUser();
992
 
993
        if ($activitygroupmode) {
994
            $course = $this->getDataGenerator()->create_course(['groupmode' => NOGROUPS, 'groupmodeforce' => 0]);
995
            $activitysettings = ['course' => $course, 'groupmode' => SEPARATEGROUPS];
996
        } else {
997
            $course = $this->getDataGenerator()->create_course(['groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1]);
998
            $activitysettings = ['course' => $course];
999
        }
1000
 
1001
        $activity = $this->getDataGenerator()->create_module('h5pactivity', $activitysettings);
1002
 
1003
        // Grant mod/h5pactivity:reviewattempts to non-editing teacher.
1004
        // At the time of writing this is not set by default (see MDL-80028).
1005
        $teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
1006
        role_change_permission($teacherrole->id,
1007
            \context_course::instance($course->id), 'mod/h5pactivity:reviewattempts', CAP_ALLOW);
1008
 
1009
        $manager = manager::create_from_instance($activity);
1010
 
1011
        $editingteacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
1012
        $teacher1 = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
1013
        $teacher2 = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
1014
        $student1 = $this->getDataGenerator()->create_and_enrol($course);
1015
        $student2 = $this->getDataGenerator()->create_and_enrol($course);
1016
        $student3 = $this->getDataGenerator()->create_and_enrol($course);
1017
 
1018
        $group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
1019
        $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $teacher1->id]);
1020
        $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $student1->id]);
1021
 
1022
        $group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
1023
        $this->getDataGenerator()->create_group_member(['groupid' => $group2->id, 'userid' => $student2->id]);
1024
 
1025
        // Check reports.
1026
 
1027
        // Editing teachers can view all users, those in any group or no group.
1028
        $this->setUser($editingteacher);
1029
        $report = $manager->get_report($student1->id);
1030
        $this->assertNotNull($report);
1031
        $report = $manager->get_report($student3->id);
1032
        $this->assertNotNull($report);
1033
 
1034
        // Non-editing teacher can view student, both members of same group.
1035
        $this->setUser($teacher1);
1036
        $report = $manager->get_report($student1->id);
1037
        $this->assertNotNull($report);
1038
 
1039
        // Non-editing teacher cannot view student in no group.
1040
        $report = $manager->get_report($student3->id);
1041
        $this->assertNull($report);
1042
 
1043
        // Non-editing teacher cannot view student in different group.
1044
        $report = $manager->get_report($student2->id);
1045
        $this->assertNull($report);
1046
 
1047
        // Non-editing teacher in no group can view no one.
1048
        $this->setUser($teacher2);
1049
        $report = $manager->get_report($student1->id);
1050
        $this->assertNull($report);
1051
        $report = $manager->get_report($student3->id);
1052
        $this->assertNull($report);
1053
    }
1054
 
1055
    /**
1056
     * Data provider for test_get_report_groupmode.
1057
     *
1058
     * @return array
1059
     */
1060
    public function get_report_data_groupmode(): array {
1061
        return [
1062
            // No tracking scenarios.
1063
            'course groupmode is SEPARATEGROUPS' => [false],
1064
            'course groupmode is NOGROUPS, activity groupmode is SEPARATEGROUPS' => [true],
1065
        ];
1066
    }
1067
 
1068
    /**
1069
     * Test get_attempt method.
1070
     *
1071
     * @dataProvider get_attempt_data
1072
     * @param string $attemptname the attempt to use
1073
     * @param string|null $result the expected attempt ID or null for none
1074
     */
1075
    public function test_get_attempt(string $attemptname, ?string $result): void {
1076
 
1077
        $this->resetAfterTest();
1078
        $this->setAdminUser();
1079
 
1080
        $course = $this->getDataGenerator()->create_course();
1081
 
1082
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
1083
        $cm = get_coursemodule_from_id('h5pactivity', $activity->cmid, 0, false, MUST_EXIST);
1084
 
1085
        $otheractivity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
1086
        $othercm = get_coursemodule_from_id('h5pactivity', $otheractivity->cmid, 0, false, MUST_EXIST);
1087
 
1088
        $manager = manager::create_from_instance($activity);
1089
 
1090
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
1091
 
1092
        $attempts = ['inexistent' => 0];
1093
 
1094
        $this->generate_fake_attempts($activity, $user, 1);
1095
        $attempt = attempt::last_attempt($user, $cm);
1096
        $attempts['current'] = $attempt->get_id();
1097
 
1098
        $this->generate_fake_attempts($otheractivity, $user, 1);
1099
        $attempt = attempt::last_attempt($user, $othercm);
1100
        $attempts['other'] = $attempt->get_id();
1101
 
1102
        $attempt = $manager->get_attempt($attempts[$attemptname]);
1103
        if ($result === null) {
1104
            $this->assertNull($attempt);
1105
        } else {
1106
            $this->assertEquals($attempts[$attemptname], $attempt->get_id());
1107
            $this->assertEquals($activity->id, $attempt->get_h5pactivityid());
1108
            $this->assertEquals($user->id, $attempt->get_userid());
1109
            $this->assertEquals(4, $attempt->get_attempt());
1110
        }
1111
    }
1112
 
1113
    /**
1114
     * Data provider for test_get_attempt.
1115
     *
1116
     * @return array
1117
     */
1118
    public function get_attempt_data(): array {
1119
        return [
1120
            'Get the current activity attempt' => [
1121
                'current', 'current'
1122
            ],
1123
            'Try to get another activity attempt' => [
1124
                'other', null
1125
            ],
1126
            'Try to get an inexistent attempt' => [
1127
                'inexistent', null
1128
            ],
1129
        ];
1130
    }
1131
 
1132
    /**
1133
     * Insert fake attempt data into h5pactiviyt_attempts.
1134
     *
1135
     * This function insert 4 attempts. 3 of them finished with different gradings
1136
     * and timestamps and 1 unfinished.
1137
     *
1138
     * @param stdClass $activity the activity record
1139
     * @param stdClass $user user record
1140
     * @param int $basescore a score to be used to generate all attempts
1141
     */
1142
    private function generate_fake_attempts(stdClass $activity, stdClass $user, int $basescore) {
1143
        global $DB;
1144
 
1145
        $attempt = (object)[
1146
            'h5pactivityid' => $activity->id,
1147
            'userid' => $user->id,
1148
            'timecreated' => $basescore,
1149
            'timemodified' => ($basescore + 10),
1150
            'attempt' => 1,
1151
            'rawscore' => $basescore,
1152
            'maxscore' => ($basescore + $basescore),
1153
            'duration' => $basescore,
1154
            'completion' => 1,
1155
            'success' => 1,
1156
        ];
1157
        $attempt->scaled = $attempt->rawscore / $attempt->maxscore;
1158
        $DB->insert_record('h5pactivity_attempts', $attempt);
1159
 
1160
        $attempt = (object)[
1161
            'h5pactivityid' => $activity->id,
1162
            'userid' => $user->id,
1163
            'timecreated' => ($basescore + 20),
1164
            'timemodified' => ($basescore + 30),
1165
            'attempt' => 2,
1166
            'rawscore' => $basescore,
1167
            'maxscore' => ($basescore + $basescore - 1),
1168
            'duration' => $basescore,
1169
            'completion' => 1,
1170
            'success' => 1,
1171
        ];
1172
        $attempt->scaled = $attempt->rawscore / $attempt->maxscore;
1173
        $DB->insert_record('h5pactivity_attempts', $attempt);
1174
 
1175
        $attempt = (object)[
1176
            'h5pactivityid' => $activity->id,
1177
            'userid' => $user->id,
1178
            'timecreated' => ($basescore + 40),
1179
            'timemodified' => ($basescore + 50),
1180
            'attempt' => 3,
1181
            'rawscore' => $basescore,
1182
            'maxscore' => ($basescore + $basescore + 1),
1183
            'duration' => $basescore,
1184
            'completion' => 1,
1185
            'success' => 0,
1186
        ];
1187
        $attempt->scaled = $attempt->rawscore / $attempt->maxscore;
1188
        $DB->insert_record('h5pactivity_attempts', $attempt);
1189
 
1190
        // Unfinished attempt.
1191
        $attempt = (object)[
1192
            'h5pactivityid' => $activity->id,
1193
            'userid' => $user->id,
1194
            'timecreated' => ($basescore + 60),
1195
            'timemodified' => ($basescore + 60),
1196
            'attempt' => 4,
1197
            'rawscore' => $basescore,
1198
            'maxscore' => $basescore,
1199
            'duration' => $basescore,
1200
        ];
1201
        $DB->insert_record('h5pactivity_attempts', $attempt);
1202
    }
1203
}