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
namespace mod_quiz\external;
18
 
19
defined('MOODLE_INTERNAL') || die();
20
 
21
require_once(__DIR__ . '/../../../../webservice/tests/helpers.php');
22
 
23
use coding_exception;
24
use core_question_generator;
25
use externallib_advanced_testcase;
26
use mod_quiz\quiz_attempt;
27
use mod_quiz\quiz_settings;
28
use required_capability_exception;
29
use stdClass;
30
 
31
/**
32
 * Test for the grade_items CRUD service.
33
 *
34
 * @package   mod_quiz
35
 * @category  external
36
 * @copyright 2023 The Open University
37
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 * @covers \mod_quiz\external\create_grade_items
39
 * @covers \mod_quiz\external\delete_grade_items
40
 * @covers \mod_quiz\external\update_grade_items
41
 * @covers \mod_quiz\structure
42
 */
43
final class grade_items_test extends externallib_advanced_testcase {
44
 
45
    public function test_create_grade_items_service_works(): void {
46
        $quizobj = $this->create_quiz_with_two_grade_items();
47
 
48
        create_grade_items::execute($quizobj->get_quizid(), [
49
            ['name' => 'Speaking'],
50
            ['name' => 'Writing'],
51
        ]);
52
 
53
        $structure = $quizobj->get_structure();
54
        $items = array_values($structure->get_grade_items());
55
 
56
        $this->assertEquals('Listening', $items[0]->name);
57
        $this->assertEquals('Reading', $items[1]->name);
58
        $this->assertEquals('Speaking', $items[2]->name);
59
        $this->assertEquals('Writing', $items[3]->name);
60
    }
61
 
62
    public function test_create_grade_items_service_checks_permissions(): void {
63
        $quizobj = $this->create_quiz_with_two_grade_items();
64
 
65
        $unprivilegeduser = $this->getDataGenerator()->create_user();
66
        $this->setUser($unprivilegeduser);
67
 
68
        $this->expectException(required_capability_exception::class);
69
        create_grade_items::execute($quizobj->get_quizid(), []);
70
    }
71
 
72
    public function test_update_grade_items_service_works(): void {
73
        $quizobj = $this->create_quiz_with_two_grade_items();
74
 
75
        $structure = $quizobj->get_structure();
76
        $items = array_values($structure->get_grade_items());
77
 
78
        update_grade_items::execute($quizobj->get_quizid(), [
79
            ['id' => $items[0]->id, 'name' => 'Speaking'],
80
            ['id' => $items[1]->id, 'name' => null],
81
        ]);
82
 
83
        $structure = $quizobj->get_structure();
84
        $updateditems = $structure->get_grade_items();
85
 
86
        $this->assertEquals('Speaking', $updateditems[$items[0]->id]->name);
87
        $this->assertEquals($items[1]->name, $updateditems[$items[1]->id]->name);
88
    }
89
 
90
    public function test_update_grade_items_service_checks_permissions(): void {
91
        $quizobj = $this->create_quiz_with_two_grade_items();
92
 
93
        $unprivilegeduser = $this->getDataGenerator()->create_user();
94
        $this->setUser($unprivilegeduser);
95
 
96
        $this->expectException(required_capability_exception::class);
97
        update_grade_items::execute($quizobj->get_quizid(), []);
98
    }
99
 
100
    public function test_delete_grade_items_service_works(): void {
101
        $quizobj = $this->create_quiz_with_two_grade_items();
102
 
103
        $structure = $quizobj->get_structure();
104
        $items = array_values($structure->get_grade_items());
105
        $structure->update_slot_grade_item($structure->get_slot_by_number(1), null);
106
        $structure->update_slot_grade_item($structure->get_slot_by_number(2), null);
107
 
108
        delete_grade_items::execute($quizobj->get_quizid(), [['id' => $items[0]->id]]);
109
 
110
        $structure = $quizobj->get_structure();
111
        $updateditems = $structure->get_grade_items();
112
 
113
        $this->assertCount(1, $updateditems);
114
        $this->assertEquals('Reading', $updateditems[$items[1]->id]->name);
115
    }
116
 
117
    public function test_cant_delete_grade_item_that_is_used(): void {
118
        $quizobj = $this->create_quiz_with_two_grade_items();
119
 
120
        $structure = $quizobj->get_structure();
121
        $items = array_values($structure->get_grade_items());
122
 
123
        $this->expectException(coding_exception::class);
124
        delete_grade_items::execute($quizobj->get_quizid(), [['id' => $items[0]->id]]);
125
    }
126
 
127
    public function test_delete_grade_items_service_checks_permissions(): void {
128
        $quizobj = $this->create_quiz_with_two_grade_items();
129
 
130
        $unprivilegeduser = $this->getDataGenerator()->create_user();
131
        $this->setUser($unprivilegeduser);
132
 
133
        $structure = $quizobj->get_structure();
134
        $items = array_values($structure->get_grade_items());
135
 
136
        $this->expectException(required_capability_exception::class);
137
        delete_grade_items::execute($quizobj->get_quizid(), [['id' => $items[0]->id]]);
138
    }
139
 
140
    public function test_get_edit_grading_page_data_service_works(): void {
141
        global $PAGE;
142
        $PAGE->set_url('/');
143
 
144
        $quizobj = $this->create_quiz_with_two_grade_items();
145
 
146
        $jsondata = get_edit_grading_page_data::execute($quizobj->get_quizid());
147
 
148
        $this->assertJson($jsondata);
149
        $data = json_decode($jsondata);
150
        $this->assertEquals($quizobj->get_quizid(), $data->quizid);
151
    }
152
 
153
    public function test_get_edit_grading_page_data_service_checks_permissions(): void {
154
        $quizobj = $this->create_quiz_with_two_grade_items();
155
 
156
        $unprivilegeduser = $this->getDataGenerator()->create_user();
157
        $this->setUser($unprivilegeduser);
158
 
159
        $this->expectException(required_capability_exception::class);
160
        get_edit_grading_page_data::execute($quizobj->get_quizid());
161
    }
162
 
163
    /**
164
     * Create a quiz of two shortanswer questions, each contributing to a different grade item.
165
     *
166
     * @return quiz_settings the newly created quiz.
167
     */
168
    protected function create_quiz_with_two_grade_items(): quiz_settings {
169
        global $SITE;
170
        $this->resetAfterTest();
171
        $this->setAdminUser();
172
 
173
        // Make a quiz.
174
        /** @var \mod_quiz_generator $quizgenerator */
175
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
176
 
177
        $quiz = $quizgenerator->create_instance(['course' => $SITE->id]);
178
 
179
        // Create two question.
180
        /** @var core_question_generator $questiongenerator */
181
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
182
        $cat = $questiongenerator->create_question_category();
183
        $saq1 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
184
        $saq2 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
185
 
186
        // Add them to the quiz.
187
        quiz_add_quiz_question($saq1->id, $quiz, 0, 1);
188
        quiz_add_quiz_question($saq2->id, $quiz, 0, 1);
189
 
190
        // Create two quiz grade items.
191
        $listeninggrade = $quizgenerator->create_grade_item(['quizid' => $quiz->id, 'name' => 'Listening']);
192
        $readinggrade = $quizgenerator->create_grade_item(['quizid' => $quiz->id, 'name' => 'Reading']);
193
 
194
        // Set the questions to use those grade items.
195
        $quizobj = quiz_settings::create($quiz->id);
196
        $structure = $quizobj->get_structure();
197
        $structure->update_slot_grade_item($structure->get_slot_by_number(1), $listeninggrade->id);
198
        $structure->update_slot_grade_item($structure->get_slot_by_number(2), $readinggrade->id);
199
        $quizobj->get_grade_calculator()->recompute_quiz_sumgrades();
200
 
201
        return $quizobj;
202
    }
203
 
204
    public function test_create_grade_item_per_section_works(): void {
205
        global $SITE;
206
        $this->resetAfterTest();
207
        $this->setAdminUser();
208
 
209
        // Create a quiz with no grade items yet, but two sections.
210
        /** @var \mod_quiz_generator $quizgenerator */
211
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
212
        $quiz = $quizgenerator->create_instance(['course' => $SITE->id]);
213
 
214
        // Create three questions.
215
        /** @var core_question_generator $questiongenerator */
216
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
217
        $cat = $questiongenerator->create_question_category();
218
        $saq1 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
219
        $saq2 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
220
        $saq3 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
221
 
222
        // Add them to the quiz.
223
        quiz_add_quiz_question($saq1->id, $quiz, 1, 1);
224
        quiz_add_quiz_question($saq2->id, $quiz, 1, 1);
225
        quiz_add_quiz_question($saq3->id, $quiz, 2, 1);
226
 
227
        // Create two sections.
228
        $quizobj = quiz_settings::create($quiz->id);
229
        $structure = $quizobj->get_structure();
230
        $defaultsection = array_values($structure->get_sections())[0];
231
        $structure->set_section_heading($defaultsection->id, 'Listening');
232
        $structure->add_section_heading(2, 'Reading');
233
 
234
        // Call the method we are testing.
235
        create_grade_item_per_section::execute($quizobj->get_quizid());
236
 
237
        // Verify.
238
        $structure = $quizobj->get_structure();
239
 
240
        $gradeitems = array_values($structure->get_grade_items());
241
        $this->assertCount(2, $gradeitems);
242
        $this->assertEquals('Listening', $gradeitems[0]->name);
243
        $this->assertEquals(1, $gradeitems[0]->sortorder);
244
        $this->assertEquals('Reading', $gradeitems[1]->name);
245
        $this->assertEquals(2, $gradeitems[1]->sortorder);
246
 
247
        $this->assertEquals($gradeitems[0]->id, $structure->get_slot_by_number(1)->quizgradeitemid);
248
        $this->assertEquals($gradeitems[0]->id, $structure->get_slot_by_number(2)->quizgradeitemid);
249
        $this->assertEquals($gradeitems[1]->id, $structure->get_slot_by_number(3)->quizgradeitemid);
250
    }
251
 
11 efrain 252
    public function test_create_grade_item_per_section_with_descriptions(): void {
253
        global $SITE;
254
        $this->resetAfterTest();
255
        $this->setAdminUser();
256
 
257
        // Create a quiz with no grade items yet, but two sections.
258
        /** @var \mod_quiz_generator $quizgenerator */
259
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
260
        $quiz = $quizgenerator->create_instance(['course' => $SITE->id]);
261
 
262
        // Create three questions.
263
        /** @var core_question_generator $questiongenerator */
264
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
265
        $cat = $questiongenerator->create_question_category();
266
        $desc1 = $questiongenerator->create_question('description', null, ['category' => $cat->id]);
267
        $desc2 = $questiongenerator->create_question('description', null, ['category' => $cat->id]);
268
        $saq1 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
269
 
270
        // Add them to the quiz.
271
        quiz_add_quiz_question($desc1->id, $quiz, 1);
272
        quiz_add_quiz_question($desc2->id, $quiz, 2);
273
        quiz_add_quiz_question($saq1->id, $quiz, 2, 7);
274
 
275
        // Create two sections.
276
        $quizobj = quiz_settings::create($quiz->id);
277
        $structure = $quizobj->get_structure();
278
        $defaultsection = array_values($structure->get_sections())[0];
279
        $structure->set_section_heading($defaultsection->id, 'Introduction');
280
        $structure->add_section_heading(2, 'The question');
281
 
282
        // Call the method we are testing.
283
        create_grade_item_per_section::execute($quizobj->get_quizid());
284
 
285
        // Verify.
286
        $structure = $quizobj->get_structure();
287
 
288
        $gradeitems = array_values($structure->get_grade_items());
289
        $this->assertCount(1, $gradeitems);
290
        $this->assertEquals('The question', $gradeitems[0]->name);
291
        $this->assertEquals(1, $gradeitems[0]->sortorder);
292
 
293
        $this->assertNull($structure->get_slot_by_number(1)->quizgradeitemid);
294
        $this->assertNull($structure->get_slot_by_number(2)->quizgradeitemid);
295
        $this->assertEquals($gradeitems[0]->id, $structure->get_slot_by_number(3)->quizgradeitemid);
296
    }
297
 
1 efrain 298
    public function test_create_grade_item_per_section_service_checks_permissions(): void {
299
        global $SITE;
300
        $this->resetAfterTest();
301
 
302
        // Create a quiz.
303
        /** @var \mod_quiz_generator $quizgenerator */
304
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
305
        $quiz = $quizgenerator->create_instance(['course' => $SITE->id]);
306
 
307
        $unprivilegeduser = $this->getDataGenerator()->create_user();
308
        $this->setUser($unprivilegeduser);
309
 
310
        $this->expectException(required_capability_exception::class);
311
        create_grade_item_per_section::execute($quiz->id);
312
    }
313
 
314
    public function test_cant_create_grade_item_per_section_if_grade_items_already_exist(): void {
315
        $quizobj = $this->create_quiz_with_two_grade_items();
316
 
317
        $this->expectException(coding_exception::class);
318
        create_grade_item_per_section::execute($quizobj->get_quizid());
319
    }
320
 
321
}