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
 * A test helper trait.
19
 *
20
 * @package    quizaccess_seb
21
 * @author     Andrew Madden <andrewmadden@catalyst-au.net>
22
 * @copyright  2019 Catalyst IT
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
use mod_quiz\local\access_rule_base;
27
use mod_quiz\quiz_attempt;
28
use quizaccess_seb\seb_access_manager;
29
use quizaccess_seb\settings_provider;
30
 
31
defined('MOODLE_INTERNAL') || die();
32
 
33
global $CFG;
34
require_once($CFG->dirroot . "/mod/quiz/accessrule/seb/rule.php"); // Include plugin rule class.
35
require_once($CFG->dirroot . "/mod/quiz/mod_form.php"); // Include plugin rule class.
36
 
37
/**
38
 * A test helper trait. It has some common helper methods.
39
 *
40
 * @copyright  2020 Catalyst IT
41
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
trait quizaccess_seb_test_helper_trait {
44
 
45
    /** @var \stdClass $course Test course to contain quiz. */
46
    protected $course;
47
 
48
    /** @var \stdClass $quiz A test quiz. */
49
    protected $quiz;
50
 
51
    /** @var \stdClass $user A test logged-in user. */
52
    protected $user;
53
 
54
    /**
55
     * Assign a capability to $USER
56
     * The function creates a student $USER if $USER->id is empty
57
     *
58
     * @param string $capability Capability name.
59
     * @param int $contextid Context ID.
60
     * @param int $roleid Role ID.
61
     * @return int The role id - mainly returned for creation, so calling function can reuse it.
62
     */
63
    protected function assign_user_capability($capability, $contextid, $roleid = null) {
64
        global $USER;
65
 
66
        // Create a new student $USER if $USER doesn't exist.
67
        if (empty($USER->id)) {
68
            $user = $this->getDataGenerator()->create_user();
69
            $this->setUser($user);
70
        }
71
 
72
        if (empty($roleid)) {
73
            $roleid = \create_role('Dummy role', 'dummyrole', 'dummy role description');
74
        }
75
 
76
        \assign_capability($capability, CAP_ALLOW, $roleid, $contextid);
77
 
78
        \role_assign($roleid, $USER->id, $contextid);
79
 
80
        \accesslib_clear_all_caches_for_unit_testing();
81
 
82
        return $roleid;
83
    }
84
 
85
    /**
86
     * Strip the seb_ prefix from each setting key.
87
     *
88
     * @param \stdClass $settings Object containing settings.
89
     * @return \stdClass The modified settings object.
90
     */
91
    protected function strip_all_prefixes(\stdClass $settings): \stdClass {
92
        $newsettings = new \stdClass();
93
        foreach ($settings as $name => $setting) {
94
            $newname = preg_replace("/^seb_/", "", $name);
95
            $newsettings->$newname = $setting; // Add new key.
96
        }
97
        return $newsettings;
98
    }
99
 
100
    /**
101
     * Creates a file in the user draft area.
102
     *
103
     * @param string $xml
104
     * @return int The user draftarea id
105
     */
106
    protected function create_test_draftarea_file(string $xml): int {
107
        global $USER;
108
 
109
        $itemid = 0;
110
        $usercontext = \context_user::instance($USER->id);
111
        $filerecord = [
112
            'contextid' => \context_user::instance($USER->id)->id,
113
            'component' => 'user',
114
            'filearea' => 'draft',
115
            'itemid' => $itemid,
116
            'filepath' => '/',
117
            'filename' => 'test.xml'
118
        ];
119
 
120
        $fs = get_file_storage();
121
        $fs->create_file_from_string($filerecord, $xml);
122
 
123
        $draftitemid = 0;
124
        file_prepare_draft_area($draftitemid, $usercontext->id, 'user', 'draft', 0);
125
 
126
        return $draftitemid;
127
    }
128
 
129
    /**
130
     * Create a file in a modules filearea.
131
     *
132
     * @param string $xml XML content of the file.
133
     * @param string $cmid Course module id.
134
     * @return int Item ID of file.
135
     */
136
    protected function create_module_test_file(string $xml, string $cmid): int {
137
        $itemid = 0;
138
        $fs = get_file_storage();
139
        $filerecord = [
140
            'contextid' => \context_module::instance($cmid)->id,
141
            'component' => 'quizaccess_seb',
142
            'filearea' => 'filemanager_sebconfigfile',
143
            'itemid' => $itemid,
144
            'filepath' => '/',
145
            'filename' => 'test.xml'
146
        ];
147
        $fs->create_file_from_string($filerecord, $xml);
148
        return $itemid;
149
    }
150
 
151
    /**
152
     * Create a test quiz for the specified course.
153
     *
154
     * @param \stdClass $course
155
     * @param int $requiresafeexambrowser How to use SEB for this quiz?
156
     * @return  array
157
     */
158
    protected function create_test_quiz($course, $requiresafeexambrowser = settings_provider::USE_SEB_NO) {
159
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
160
 
161
        $quiz = $quizgenerator->create_instance([
162
            'course' => $course->id,
163
            'questionsperpage' => 0,
164
            'grade' => 100.0,
165
            'sumgrades' => 2,
166
            'seb_requiresafeexambrowser' => $requiresafeexambrowser,
167
        ]);
168
        $quiz->seb_showsebdownloadlink = 1;
169
        $quiz->coursemodule = $quiz->cmid;
170
 
1441 ariadna 171
        // Create a question bank.
172
        $qbank = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
173
        $qbankcontext = context_module::instance($qbank->cmid);
174
 
1 efrain 175
        // Create a couple of questions.
176
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
1441 ariadna 177
        $cat = $questiongenerator->create_question_category(['contextid' => $qbankcontext->id]);
1 efrain 178
 
179
        $saq = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
180
        quiz_add_quiz_question($saq->id, $quiz);
181
        $numq = $questiongenerator->create_question('numerical', null, ['category' => $cat->id]);
182
        quiz_add_quiz_question($numq->id, $quiz);
183
 
184
        return $quiz;
185
    }
186
 
187
    /**
188
     * Answer questions for a quiz + user.
189
     *
190
     * @param \stdClass $quiz Quiz to attempt.
191
     * @param \stdClass $user A user to attempt the quiz.
192
     * @return  array
193
     */
194
    protected function attempt_quiz($quiz, $user) {
195
        $this->setUser($user);
196
 
197
        $starttime = time();
198
        $quizobj = mod_quiz\quiz_settings::create($quiz->id, $user->id);
199
 
200
        $quba = \question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
201
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
202
 
203
        // Start the attempt.
204
        $attempt = quiz_create_attempt($quizobj, 1, false, $starttime, false, $user->id);
205
        quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $starttime);
206
        quiz_attempt_save_started($quizobj, $quba, $attempt);
207
 
208
        // Answer the questions.
209
        $attemptobj = quiz_attempt::create($attempt->id);
210
 
211
        $tosubmit = [
212
            1 => ['answer' => 'frog'],
213
            2 => ['answer' => '3.14'],
214
        ];
215
 
216
        $attemptobj->process_submitted_actions($starttime, false, $tosubmit);
217
 
218
        // Finish the attempt.
219
        $attemptobj = quiz_attempt::create($attempt->id);
1441 ariadna 220
        $attemptobj->process_submit($starttime, false);
221
        $attemptobj->process_grade_submission($starttime);
1 efrain 222
 
223
        $this->setUser();
224
 
225
        return [$quizobj, $quba, $attemptobj];
226
    }
227
 
228
    /**
229
     * Create test template.
230
     *
231
     * @param string|null $xml Template content.
232
     * @return \quizaccess_seb\template Just created template.
233
     */
1441 ariadna 234
    public function create_template(?string $xml = null) {
1 efrain 235
        $data = [];
236
 
237
        if (!is_null($xml)) {
238
            $data['content'] = $xml;
239
        }
240
 
241
        return $this->getDataGenerator()->get_plugin_generator('quizaccess_seb')->create_template($data);
242
    }
243
 
244
    /**
245
     * Get access manager for testing.
246
     *
247
     * @return \quizaccess_seb\seb_access_manager
248
     */
249
    protected function get_access_manager() {
250
        return new seb_access_manager(new mod_quiz\quiz_settings($this->quiz,
251
            get_coursemodule_from_id('quiz', $this->quiz->cmid), $this->course));
252
    }
253
 
254
    /**
255
     * A helper method to make the rule form the currently created quiz and  course.
256
     *
257
     * @return access_rule_base|null
258
     */
259
    protected function make_rule() {
260
        return \quizaccess_seb::make(
261
            new mod_quiz\quiz_settings($this->quiz, get_coursemodule_from_id('quiz', $this->quiz->cmid), $this->course),
262
            0,
263
            true
264
        );
265
    }
266
 
267
    /**
268
     * A helper method to set up quiz view page.
269
     */
270
    protected function set_up_quiz_view_page() {
271
        global $PAGE;
272
 
273
        $page = new \moodle_page();
274
        $page->set_context(\context_module::instance($this->quiz->cmid));
275
        $page->set_course($this->course);
276
        $page->set_pagelayout('standard');
277
        $page->set_pagetype("mod-quiz-view");
278
        $page->set_url('/mod/quiz/view.php?id=' . $this->quiz->cmid);
279
 
280
        $PAGE = $page;
281
    }
282
 
283
    /**
284
     * Get a test object containing mock test settings.
285
     *
286
     * @return \stdClass Settings.
287
     */
288
    protected function get_test_settings(array $settings = []): \stdClass {
289
        return (object) array_merge([
290
            'quizid' => 1,
291
            'cmid' => 1,
292
            'requiresafeexambrowser' => '1',
293
            'showsebtaskbar' => '1',
294
            'showwificontrol' => '0',
295
            'showreloadbutton' => '1',
296
            'showtime' => '0',
297
            'showkeyboardlayout' => '1',
298
            'allowuserquitseb' => '1',
299
            'quitpassword' => 'test',
300
            'linkquitseb' => '',
301
            'userconfirmquit' => '1',
302
            'enableaudiocontrol' => '1',
303
            'muteonstartup' => '0',
1441 ariadna 304
            'allowcapturecamera' => '1',
305
            'allowcapturemicrophone' => '1',
1 efrain 306
            'allowspellchecking' => '0',
307
            'allowreloadinexam' => '1',
308
            'activateurlfiltering' => '1',
309
            'filterembeddedcontent' => '0',
310
            'expressionsallowed' => 'test.com',
311
            'regexallowed' => '',
312
            'expressionsblocked' => '',
313
            'regexblocked' => '',
314
            'showsebdownloadlink' => '1',
315
        ], $settings);
316
    }
317
 
318
}