Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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
namespace mod_quiz\tests;
18
 
19
use backup;
20
use backup_controller;
21
use component_generator_base;
22
use mod_quiz_generator;
23
use mod_quiz\quiz_attempt;
24
use mod_quiz\quiz_settings;
25
use restore_controller;
26
use stdClass;
27
use question_engine;
28
 
29
/**
30
 * Helper trait for quiz question unit tests.
31
 *
32
 * This trait helps to execute different tests for quiz, for example if it needs to create a quiz, add question
33
 * to the question, add random quetion to the quiz, do a backup or restore.
34
 *
35
 * @package    mod_quiz
36
 * @category   test
37
 * @copyright  2021 Catalyst IT Australia Pty Ltd
38
 * @author     Safat Shahin <safatshahin@catalyst-au.net>
39
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 */
41
trait question_helper_test_trait {
42
    /** @var stdClass $course Test course to contain quiz. */
43
    protected $course;
44
 
45
    /** @var stdClass $quiz A test quiz. */
46
    protected $quiz;
47
 
48
    /** @var stdClass $user A test logged-in user. */
49
    protected $user;
50
 
51
    /**
52
     * Create a test quiz for the specified course.
53
     *
54
     * @param stdClass $course
55
     * @return  stdClass
56
     */
57
    protected function create_test_quiz(stdClass $course): stdClass {
58
        /** @var mod_quiz_generator $quizgenerator */
59
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
60
 
61
        return $quizgenerator->create_instance([
62
            'course' => $course->id,
63
            'questionsperpage' => 0,
64
            'grade' => 100.0,
65
            'sumgrades' => 2,
66
        ]);
67
    }
68
 
69
    /**
70
     * Helper method to add regular questions in quiz.
71
     *
72
     * @param component_generator_base $questiongenerator
73
     * @param stdClass $quiz
74
     * @param array $override
75
     */
76
    protected function add_two_regular_questions($questiongenerator, stdClass $quiz, $override = null): void {
77
        // Create a couple of questions.
78
        $cat = $questiongenerator->create_question_category($override);
79
 
80
        $saq = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
81
        // Create another version.
82
        $questiongenerator->update_question($saq);
83
        quiz_add_quiz_question($saq->id, $quiz);
84
        $numq = $questiongenerator->create_question('numerical', null, ['category' => $cat->id]);
85
        // Create two version.
86
        $questiongenerator->update_question($numq);
87
        $questiongenerator->update_question($numq);
88
        quiz_add_quiz_question($numq->id, $quiz);
89
    }
90
 
91
    /**
92
     * Helper method to add random question to quiz.
93
     *
94
     * @param component_generator_base $questiongenerator
95
     * @param stdClass $quiz
96
     * @param array $override
97
     */
98
    protected function add_one_random_question($questiongenerator, stdClass $quiz, $override = []): void {
99
        // Create a random question.
100
        $cat = $questiongenerator->create_question_category($override);
101
        $questiongenerator->create_question('truefalse', null, ['category' => $cat->id]);
102
        $questiongenerator->create_question('essay', null, ['category' => $cat->id]);
103
        $this->add_random_questions($quiz->id, 0, $cat->id, 1);
104
    }
105
 
106
    /**
107
     * Attempt questions for a quiz and user.
108
     *
109
     * @param stdClass $quiz Quiz to attempt.
110
     * @param stdClass $user A user to attempt the quiz.
111
     * @param int $attemptnumber
112
     * @return array
113
     */
114
    protected function attempt_quiz(stdClass $quiz, stdClass $user, $attemptnumber = 1): array {
115
        $this->setUser($user);
116
 
117
        $starttime = time();
118
        $quizobj = quiz_settings::create($quiz->id, $user->id);
119
 
120
        $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
121
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
122
 
123
        // Start the attempt.
124
        $attempt = quiz_create_attempt($quizobj, $attemptnumber, null, $starttime, false, $user->id);
125
        quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $starttime);
126
        quiz_attempt_save_started($quizobj, $quba, $attempt);
127
 
128
        // Finish the attempt.
129
        $attemptobj = quiz_attempt::create($attempt->id);
130
        $attemptobj->process_submit($starttime, false);
131
        $attemptobj->process_grade_submission($starttime);
132
 
133
        $this->setUser();
134
        return [$quizobj, $quba, $attemptobj];
135
    }
136
 
137
    /**
138
     * A helper method to backup test quiz.
139
     *
140
     * @param stdClass $quiz Quiz to attempt.
141
     * @param stdClass $user A user to attempt the quiz.
142
     * @return string A backup ID ready to be restored.
143
     */
144
    protected function backup_quiz(stdClass $quiz, stdClass $user): string {
145
        global $CFG;
146
 
147
        // Get the necessary files to perform backup and restore.
148
        require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
149
        require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
150
 
151
        $backupid = 'test-question-backup-restore';
152
 
153
        $bc = new backup_controller(
154
            backup::TYPE_1ACTIVITY,
155
            $quiz->cmid,
156
            backup::FORMAT_MOODLE,
157
            backup::INTERACTIVE_NO,
158
            backup::MODE_GENERAL,
159
            $user->id,
160
        );
161
        $bc->execute_plan();
162
 
163
        $results = $bc->get_results();
164
        $file = $results['backup_destination'];
165
        $fp = get_file_packer('application/vnd.moodle.backup');
166
        $filepath = $CFG->dataroot . '/temp/backup/' . $backupid;
167
        $file->extract_to_pathname($fp, $filepath);
168
        $bc->destroy();
169
 
170
        return $backupid;
171
    }
172
 
173
    /**
174
     * A helper method to restore provided backup.
175
     *
176
     * @param string $backupid Backup ID to restore.
177
     * @param stdClass $course
178
     * @param stdClass $user
179
     */
180
    protected function restore_quiz(string $backupid, stdClass $course, stdClass $user): void {
181
        $rc = new restore_controller(
182
            $backupid,
183
            $course->id,
184
            backup::INTERACTIVE_NO,
185
            backup::MODE_GENERAL,
186
            $user->id,
187
            backup::TARGET_CURRENT_ADDING
188
        );
189
        $this->assertTrue($rc->execute_precheck());
190
        $rc->execute_plan();
191
        $rc->destroy();
192
    }
193
 
194
    /**
195
     * A helper method to emulate duplication of the quiz.
196
     *
197
     * @param stdClass $course
198
     * @param stdClass $quiz
199
     * @return \cm_info|null
200
     */
201
    protected function duplicate_quiz($course, $quiz): ?\cm_info {
202
        return duplicate_module($course, get_fast_modinfo($course)->get_cm($quiz->cmid));
203
    }
204
 
205
    /**
206
     * Add random questions to a quiz, with a filter condition based on a category ID.
207
     *
208
     * @param int $quizid The quiz to add the questions to.
209
     * @param int $page The page number to add the questions to.
210
     * @param int $categoryid The category ID to use for the filter condition.
211
     * @param int $number The number of questions to add.
212
     * @return void
213
     */
214
    protected function add_random_questions(int $quizid, int $page, int $categoryid, int $number): void {
215
        $quizobj = quiz_settings::create($quizid);
216
        $structure = $quizobj->get_structure();
217
        $filtercondition = [
218
            'filter' => [
219
                'category' => [
220
                    'jointype' => \core_question\local\bank\condition::JOINTYPE_DEFAULT,
221
                    'values' => [$categoryid],
222
                    'filteroptions' => ['includesubcategories' => false],
223
                ],
224
            ],
225
        ];
226
        $structure->add_random_questions($page, $number, $filtercondition);
227
    }
228
}