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
 * This file contains tests for scorm events.
19
 *
20
 * @package    mod_scorm
21
 * @copyright  2013 onwards Ankit Agarwal
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace mod_scorm\event;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
global $CFG;
30
require_once($CFG->dirroot . '/mod/scorm/locallib.php');
31
require_once($CFG->dirroot . '/mod/scorm/lib.php');
32
 
33
/**
34
 * Test class for various events related to Scorm.
35
 *
36
 * @package    mod_scorm
37
 * @copyright  2013 onwards Ankit Agarwal
38
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class events_test extends \advanced_testcase {
41
 
42
    /** @var stdClass store course object */
43
    protected $eventcourse;
44
 
45
    /** @var stdClass store user object */
46
    protected $eventuser;
47
 
48
    /** @var stdClass store scorm object */
49
    protected $eventscorm;
50
 
51
    /** @var stdClass store course module object */
52
    protected $eventcm;
53
 
54
    protected function setUp(): void {
55
        $this->setAdminUser();
56
        $this->eventcourse = $this->getDataGenerator()->create_course();
57
        $this->eventuser = $this->getDataGenerator()->create_user();
58
        $record = new \stdClass();
59
        $record->course = $this->eventcourse->id;
60
        $this->eventscorm = $this->getDataGenerator()->create_module('scorm', $record);
61
        $this->eventcm = get_coursemodule_from_instance('scorm', $this->eventscorm->id);
62
    }
63
 
64
    /**
65
     * Tests for attempt deleted event
66
     */
11 efrain 67
    public function test_attempt_deleted_event(): void {
1 efrain 68
 
69
        global $USER;
70
 
71
        $this->resetAfterTest();
72
        scorm_insert_track(2, $this->eventscorm->id, 1, 4, 'cmi.core.score.raw', 10);
73
        $sink = $this->redirectEvents();
74
        scorm_delete_attempt(2, $this->eventscorm, 4);
75
        $events = $sink->get_events();
76
        $sink->close();
77
        $event = reset($events);
78
 
79
        // Verify data.
80
        $this->assertCount(3, $events);
81
        $this->assertInstanceOf('\mod_scorm\event\attempt_deleted', $event);
82
        $this->assertEquals($USER->id, $event->userid);
83
        $this->assertEquals(\context_module::instance($this->eventcm->id), $event->get_context());
84
        $this->assertEquals(4, $event->other['attemptid']);
85
        $this->assertEquals(2, $event->relateduserid);
86
        $this->assertEventContextNotUsed($event);
87
 
88
        // Test event validations.
89
        $this->expectException(\coding_exception::class);
90
        \mod_scorm\event\attempt_deleted::create(array(
91
            'contextid' => 5,
92
            'relateduserid' => 2
93
        ));
94
    }
95
 
96
    /**
97
     * Tests for interactions viewed validations.
98
     */
11 efrain 99
    public function test_interactions_viewed_event_validations(): void {
1 efrain 100
        $this->resetAfterTest();
101
        try {
102
            \mod_scorm\event\interactions_viewed::create(array(
103
                'context' => \context_module::instance($this->eventcm->id),
104
                'courseid' => $this->eventcourse->id,
105
                'other' => array('attemptid' => 2)
106
            ));
107
            $this->fail("Event validation should not allow \\mod_scorm\\event\\interactions_viewed to be triggered without
108
                    other['instanceid']");
109
        } catch (\Exception $e) {
110
            $this->assertInstanceOf('coding_exception', $e);
111
        }
112
        try {
113
            \mod_scorm\event\interactions_viewed::create(array(
114
                'context' => \context_module::instance($this->eventcm->id),
115
                'courseid' => $this->eventcourse->id,
116
                'other' => array('instanceid' => 2)
117
            ));
118
            $this->fail("Event validation should not allow \\mod_scorm\\event\\interactions_viewed to be triggered without
119
                    other['attemptid']");
120
        } catch (\Exception $e) {
121
            $this->assertInstanceOf('coding_exception', $e);
122
        }
123
    }
124
 
125
    /**
126
     * Tests for tracks viewed event validations.
127
     */
11 efrain 128
    public function test_tracks_viewed_event_validations(): void {
1 efrain 129
        $this->resetAfterTest();
130
        try {
131
            \mod_scorm\event\tracks_viewed::create(array(
132
                'context' => \context_module::instance($this->eventcm->id),
133
                'courseid' => $this->eventcourse->id,
134
                'other' => array('attemptid' => 2, 'scoid' => 2)
135
            ));
136
            $this->fail("Event validation should not allow \\mod_scorm\\event\\tracks_viewed to be triggered without
137
                    other['instanceid']");
138
        } catch (\Exception $e) {
139
            $this->assertInstanceOf('coding_exception', $e);
140
        }
141
        try {
142
            \mod_scorm\event\tracks_viewed::create(array(
143
                'context' => \context_module::instance($this->eventcm->id),
144
                'courseid' => $this->eventcourse->id,
145
                'other' => array('instanceid' => 2, 'scoid' => 2)
146
            ));
147
            $this->fail("Event validation should not allow \\mod_scorm\\event\\tracks_viewed to be triggered without
148
                    other['attemptid']");
149
        } catch (\Exception $e) {
150
            $this->assertInstanceOf('coding_exception', $e);
151
        }
152
 
153
        try {
154
            \mod_scorm\event\tracks_viewed::create(array(
155
                'context' => \context_module::instance($this->eventcm->id),
156
                'courseid' => $this->eventcourse->id,
157
                'other' => array('attemptid' => 2, 'instanceid' => 2)
158
            ));
159
            $this->fail("Event validation should not allow \\mod_scorm\\event\\tracks_viewed to be triggered without
160
                    other['scoid']");
161
        } catch (\Exception $e) {
162
            $this->assertInstanceOf('coding_exception', $e);
163
        }
164
    }
165
 
166
    /**
167
     * Tests for userreport viewed event validations.
168
     */
11 efrain 169
    public function test_user_report_viewed_event_validations(): void {
1 efrain 170
        $this->resetAfterTest();
171
        try {
172
            \mod_scorm\event\user_report_viewed::create(array(
173
                'context' => \context_module::instance($this->eventcm->id),
174
                'courseid' => $this->eventcourse->id,
175
                'other' => array('attemptid' => 2)
176
            ));
177
            $this->fail("Event validation should not allow \\mod_scorm\\event\\user_report_viewed to be triggered without
178
                    other['instanceid']");
179
        } catch (\Exception $e) {
180
            $this->assertInstanceOf('coding_exception', $e);
181
        }
182
        try {
183
            \mod_scorm\event\user_report_viewed::create(array(
184
                'context' => \context_module::instance($this->eventcm->id),
185
                'courseid' => $this->eventcourse->id,
186
                'other' => array('instanceid' => 2)
187
            ));
188
            $this->fail("Event validation should not allow \\mod_scorm\\event\\user_report_viewed to be triggered without
189
                    other['attemptid']");
190
        } catch (\Exception $e) {
191
            $this->assertInstanceOf('coding_exception', $e);
192
        }
193
    }
194
 
195
    /**
196
     * dataProvider for test_scoreraw_submitted_event().
197
     */
198
    public function get_scoreraw_submitted_event_provider() {
199
        return array(
200
            // SCORM 1.2.
201
            // - cmi.core.score.raw.
202
            'cmi.core.score.raw => 100' => array('cmi.core.score.raw', '100'),
203
            'cmi.core.score.raw => 90' => array('cmi.core.score.raw', '90'),
204
            'cmi.core.score.raw => 50' => array('cmi.core.score.raw', '50'),
205
            'cmi.core.score.raw => 10' => array('cmi.core.score.raw', '10'),
206
            // Check an edge case (PHP empty() vs isset()): score value equals to '0'.
207
            'cmi.core.score.raw => 0' => array('cmi.core.score.raw', '0'),
208
            // SCORM 1.3 AKA 2004.
209
            // - cmi.score.raw.
210
            'cmi.score.raw => 100' => array('cmi.score.raw', '100'),
211
            'cmi.score.raw => 90' => array('cmi.score.raw', '90'),
212
            'cmi.score.raw => 50' => array('cmi.score.raw', '50'),
213
            'cmi.score.raw => 10' => array('cmi.score.raw', '10'),
214
            // Check an edge case (PHP empty() vs isset()): score value equals to '0'.
215
            'cmi.score.raw => 0' => array('cmi.score.raw', '0'),
216
        );
217
    }
218
 
219
    /**
220
     * dataProvider for test_scoreraw_submitted_event_validations().
221
     */
222
    public function get_scoreraw_submitted_event_validations() {
223
        return array(
224
            'scoreraw_submitted => missing cmielement' => array(
225
                null, '50',
226
                "Event validation should not allow \\mod_scorm\\event\\scoreraw_submitted " .
227
                    "to be triggered without other['cmielement']",
228
                'Coding error detected, it must be fixed by a programmer: ' .
229
                    "The 'cmielement' must be set in other."
230
            ),
231
            'scoreraw_submitted => missing cmivalue' => array(
232
                'cmi.core.score.raw', null,
233
                "Event validation should not allow \\mod_scorm\\event\\scoreraw_submitted " .
234
                    "to be triggered without other['cmivalue']",
235
                'Coding error detected, it must be fixed by a programmer: ' .
236
                    "The 'cmivalue' must be set in other."
237
            ),
238
            'scoreraw_submitted => wrong CMI element' => array(
239
                'cmi.core.lesson_status', '50',
240
                "Event validation should not allow \\mod_scorm\\event\\scoreraw_submitted " .
241
                    'to be triggered with a CMI element not representing a raw score',
242
                'Coding error detected, it must be fixed by a programmer: ' .
243
                    "The 'cmielement' must represents a valid CMI raw score (cmi.core.lesson_status)."
244
            ),
245
        );
246
    }
247
 
248
    /**
249
     * Tests for score submitted event validations.
250
     *
251
     * @dataProvider get_scoreraw_submitted_event_validations
252
     *
253
     * @param string $cmielement a valid CMI raw score element
254
     * @param string $cmivalue a valid CMI raw score value
255
     * @param string $failmessage the message used to fail the test in case of missing to violate a validation rule
256
     * @param string $excmessage the exception message when violating the validations rules
257
     */
11 efrain 258
    public function test_scoreraw_submitted_event_validations($cmielement, $cmivalue, $failmessage, $excmessage): void {
1 efrain 259
        $this->resetAfterTest();
260
        try {
261
            $data = array(
262
                'context' => \context_module::instance($this->eventcm->id),
263
                'courseid' => $this->eventcourse->id,
264
                'other' => array('attemptid' => 2)
265
            );
266
            if ($cmielement != null) {
267
                $data['other']['cmielement'] = $cmielement;
268
            }
269
            if ($cmivalue != null) {
270
                $data['other']['cmivalue'] = $cmivalue;
271
            }
272
            \mod_scorm\event\scoreraw_submitted::create($data);
273
            $this->fail($failmessage);
274
        } catch (\Exception $e) {
275
            $this->assertInstanceOf('coding_exception', $e);
276
            $this->assertEquals($excmessage, $e->getMessage());
277
        }
278
    }
279
 
280
    /**
281
     * dataProvider for test_status_submitted_event().
282
     */
283
    public function get_status_submitted_event_provider() {
284
        return array(
285
            // SCORM 1.2.
286
            // 1. Status: cmi.core.lesson_status.
287
            'cmi.core.lesson_status => passed' => array('cmi.core.lesson_status', 'passed'),
288
            'cmi.core.lesson_status => completed' => array('cmi.core.lesson_status', 'completed'),
289
            'cmi.core.lesson_status => failed' => array('cmi.core.lesson_status', 'failed'),
290
            'cmi.core.lesson_status => incomplete' => array('cmi.core.lesson_status', 'incomplete'),
291
            'cmi.core.lesson_status => browsed' => array('cmi.core.lesson_status', 'browsed'),
292
            'cmi.core.lesson_status => not attempted' => array('cmi.core.lesson_status', 'not attempted'),
293
            // SCORM 1.3 AKA 2004.
294
            // 1. Completion status: cmi.completion_status.
295
            'cmi.completion_status => completed' => array('cmi.completion_status', 'completed'),
296
            'cmi.completion_status => incomplete' => array('cmi.completion_status', 'incomplete'),
297
            'cmi.completion_status => not attempted' => array('cmi.completion_status', 'not attempted'),
298
            'cmi.completion_status => unknown' => array('cmi.completion_status', 'unknown'),
299
            // 2. Success status: cmi.success_status.
300
            'cmi.success_status => passed' => array('cmi.success_status', 'passed'),
301
            'cmi.success_status => failed' => array('cmi.success_status', 'failed'),
302
            'cmi.success_status => unknown' => array('cmi.success_status', 'unknown')
303
        );
304
    }
305
 
306
    /**
307
     * dataProvider for test_status_submitted_event_validations().
308
     */
309
    public function get_status_submitted_event_validations() {
310
        return array(
311
            'status_submitted => missing cmielement' => array(
312
                null, 'passed',
313
                "Event validation should not allow \\mod_scorm\\event\\status_submitted " .
314
                    "to be triggered without other['cmielement']",
315
                'Coding error detected, it must be fixed by a programmer: ' .
316
                    "The 'cmielement' must be set in other."
317
            ),
318
            'status_submitted => missing cmivalue' => array(
319
                'cmi.core.lesson_status', null,
320
                "Event validation should not allow \\mod_scorm\\event\\status_submitted " .
321
                    "to be triggered without other['cmivalue']",
322
                'Coding error detected, it must be fixed by a programmer: ' .
323
                    "The 'cmivalue' must be set in other."
324
            ),
325
            'status_submitted => wrong CMI element' => array(
326
                'cmi.core.score.raw', 'passed',
327
                "Event validation should not allow \\mod_scorm\\event\\status_submitted " .
328
                    'to be triggered with a CMI element not representing a valid CMI status element',
329
                'Coding error detected, it must be fixed by a programmer: ' .
330
                    "The 'cmielement' must represents a valid CMI status element (cmi.core.score.raw)."
331
            ),
332
            'status_submitted => wrong CMI value' => array(
333
                'cmi.core.lesson_status', 'blahblahblah',
334
                "Event validation should not allow \\mod_scorm\\event\\status_submitted " .
335
                    'to be triggered with a CMI element not representing a valid CMI status',
336
                'Coding error detected, it must be fixed by a programmer: ' .
337
                    "The 'cmivalue' must represents a valid CMI status value (blahblahblah)."
338
            ),
339
        );
340
    }
341
 
342
    /**
343
     * Tests for status submitted event validations.
344
     *
345
     * @dataProvider get_status_submitted_event_validations
346
     *
347
     * @param string $cmielement a valid CMI status element
348
     * @param string $cmivalue a valid CMI status value
349
     * @param string $failmessage the message used to fail the test in case of missing to violate a validation rule
350
     * @param string $excmessage the exception message when violating the validations rules
351
     */
11 efrain 352
    public function test_status_submitted_event_validations($cmielement, $cmivalue, $failmessage, $excmessage): void {
1 efrain 353
        $this->resetAfterTest();
354
        try {
355
            $data = array(
356
                'context' => \context_module::instance($this->eventcm->id),
357
                'courseid' => $this->eventcourse->id,
358
                'other' => array('attemptid' => 2)
359
            );
360
            if ($cmielement != null) {
361
                $data['other']['cmielement'] = $cmielement;
362
            }
363
            if ($cmivalue != null) {
364
                $data['other']['cmivalue'] = $cmivalue;
365
            }
366
            \mod_scorm\event\status_submitted::create($data);
367
            $this->fail($failmessage);
368
        } catch (\Exception $e) {
369
            $this->assertInstanceOf('coding_exception', $e);
370
            $this->assertEquals($excmessage, $e->getMessage());
371
        }
372
    }
373
}