Proyectos de Subversion Moodle

Rev

| 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
 
171
        // Create a couple of questions.
172
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
173
        $cat = $questiongenerator->create_question_category();
174
 
175
        $saq = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
176
        quiz_add_quiz_question($saq->id, $quiz);
177
        $numq = $questiongenerator->create_question('numerical', null, ['category' => $cat->id]);
178
        quiz_add_quiz_question($numq->id, $quiz);
179
 
180
        return $quiz;
181
    }
182
 
183
    /**
184
     * Answer questions for a quiz + user.
185
     *
186
     * @param \stdClass $quiz Quiz to attempt.
187
     * @param \stdClass $user A user to attempt the quiz.
188
     * @return  array
189
     */
190
    protected function attempt_quiz($quiz, $user) {
191
        $this->setUser($user);
192
 
193
        $starttime = time();
194
        $quizobj = mod_quiz\quiz_settings::create($quiz->id, $user->id);
195
 
196
        $quba = \question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
197
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
198
 
199
        // Start the attempt.
200
        $attempt = quiz_create_attempt($quizobj, 1, false, $starttime, false, $user->id);
201
        quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $starttime);
202
        quiz_attempt_save_started($quizobj, $quba, $attempt);
203
 
204
        // Answer the questions.
205
        $attemptobj = quiz_attempt::create($attempt->id);
206
 
207
        $tosubmit = [
208
            1 => ['answer' => 'frog'],
209
            2 => ['answer' => '3.14'],
210
        ];
211
 
212
        $attemptobj->process_submitted_actions($starttime, false, $tosubmit);
213
 
214
        // Finish the attempt.
215
        $attemptobj = quiz_attempt::create($attempt->id);
216
        $attemptobj->process_finish($starttime, false);
217
 
218
        $this->setUser();
219
 
220
        return [$quizobj, $quba, $attemptobj];
221
    }
222
 
223
    /**
224
     * Create test template.
225
     *
226
     * @param string|null $xml Template content.
227
     * @return \quizaccess_seb\template Just created template.
228
     */
229
    public function create_template(string $xml = null) {
230
        $data = [];
231
 
232
        if (!is_null($xml)) {
233
            $data['content'] = $xml;
234
        }
235
 
236
        return $this->getDataGenerator()->get_plugin_generator('quizaccess_seb')->create_template($data);
237
    }
238
 
239
    /**
240
     * Get access manager for testing.
241
     *
242
     * @return \quizaccess_seb\seb_access_manager
243
     */
244
    protected function get_access_manager() {
245
        return new seb_access_manager(new mod_quiz\quiz_settings($this->quiz,
246
            get_coursemodule_from_id('quiz', $this->quiz->cmid), $this->course));
247
    }
248
 
249
    /**
250
     * A helper method to make the rule form the currently created quiz and  course.
251
     *
252
     * @return access_rule_base|null
253
     */
254
    protected function make_rule() {
255
        return \quizaccess_seb::make(
256
            new mod_quiz\quiz_settings($this->quiz, get_coursemodule_from_id('quiz', $this->quiz->cmid), $this->course),
257
            0,
258
            true
259
        );
260
    }
261
 
262
    /**
263
     * A helper method to set up quiz view page.
264
     */
265
    protected function set_up_quiz_view_page() {
266
        global $PAGE;
267
 
268
        $page = new \moodle_page();
269
        $page->set_context(\context_module::instance($this->quiz->cmid));
270
        $page->set_course($this->course);
271
        $page->set_pagelayout('standard');
272
        $page->set_pagetype("mod-quiz-view");
273
        $page->set_url('/mod/quiz/view.php?id=' . $this->quiz->cmid);
274
 
275
        $PAGE = $page;
276
    }
277
 
278
    /**
279
     * Get a test object containing mock test settings.
280
     *
281
     * @return \stdClass Settings.
282
     */
283
    protected function get_test_settings(array $settings = []): \stdClass {
284
        return (object) array_merge([
285
            'quizid' => 1,
286
            'cmid' => 1,
287
            'requiresafeexambrowser' => '1',
288
            'showsebtaskbar' => '1',
289
            'showwificontrol' => '0',
290
            'showreloadbutton' => '1',
291
            'showtime' => '0',
292
            'showkeyboardlayout' => '1',
293
            'allowuserquitseb' => '1',
294
            'quitpassword' => 'test',
295
            'linkquitseb' => '',
296
            'userconfirmquit' => '1',
297
            'enableaudiocontrol' => '1',
298
            'muteonstartup' => '0',
299
            'allowspellchecking' => '0',
300
            'allowreloadinexam' => '1',
301
            'activateurlfiltering' => '1',
302
            'filterembeddedcontent' => '0',
303
            'expressionsallowed' => 'test.com',
304
            'regexallowed' => '',
305
            'expressionsblocked' => '',
306
            'regexblocked' => '',
307
            'showsebdownloadlink' => '1',
308
        ], $settings);
309
    }
310
 
311
}