Proyectos de Subversion Moodle

Rev

Rev 11 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 11 Rev 1441
Línea 14... Línea 14...
14
// You should have received a copy of the GNU General Public License
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/>.
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
Línea 16... Línea 16...
16
 
16
 
Línea -... Línea 17...
-
 
17
namespace core;
-
 
18
 
17
namespace core;
19
use core_question\local\bank\question_bank_helper;
Línea 18... Línea 20...
18
 
20
use mod_quiz\quiz_settings;
Línea 19... Línea 21...
19
use question_bank;
21
use question_bank;
Línea 35... Línea 37...
35
 * @package    core
37
 * @package    core
36
 * @category   test
38
 * @category   test
37
 * @copyright  2006 The Open University
39
 * @copyright  2006 The Open University
38
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
41
 */
40
class questionlib_test extends \advanced_testcase {
42
final class questionlib_test extends \advanced_testcase {
Línea 41... Línea 43...
41
 
43
 
42
    /**
44
    /**
43
     * Test set up.
45
     * Test set up.
44
     *
46
     *
45
     * This is executed before running any test in this file.
47
     * This is executed before running any test in this file.
46
     */
48
     */
-
 
49
    public function setUp(): void {
47
    public function setUp(): void {
50
        parent::setUp();
48
        $this->resetAfterTest();
51
        $this->resetAfterTest();
Línea 49... Línea 52...
49
    }
52
    }
-
 
53
 
-
 
54
    /**
-
 
55
     * Generate a course and question bank module instance for use in test cases, and return the bank context.
-
 
56
     * @return \core\context\module
-
 
57
     */
-
 
58
    protected function create_course_and_question_bank(): \core\context\module {
-
 
59
        $course = self::getDataGenerator()->create_course();
-
 
60
        $qbank = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
-
 
61
        return \context_module::instance($qbank->cmid);
-
 
62
    }
50
 
63
 
51
    /**
64
    /**
52
     * Setup a course, a quiz, a question category and a question for testing.
-
 
53
     *
65
     * Setup a course, a quiz, a question category and a question for testing.
54
     * @param string $type The type of question category to create.
66
     *
55
     * @return array The created data objects
67
     * @return array The created data objects
56
     */
68
     */
57
    public function setup_quiz_and_questions($type = 'module') {
69
    public function setup_quiz_and_questions() {
Línea 58... Línea 70...
58
        // Create course category.
70
        // Create course category.
59
        $category = $this->getDataGenerator()->create_category();
71
        $category = $this->getDataGenerator()->create_category();
Línea 73... Línea 85...
73
        $quiz = $this->getDataGenerator()->create_module('quiz', $options);
85
        $quiz = $this->getDataGenerator()->create_module('quiz', $options);
Línea 74... Línea 86...
74
 
86
 
75
        /** @var \core_question_generator $qgen */
87
        /** @var \core_question_generator $qgen */
Línea 76... Línea -...
76
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
-
 
77
 
-
 
78
        switch ($type) {
-
 
79
            case 'course':
-
 
80
                $context = \context_course::instance($course->id);
-
 
81
                break;
-
 
82
 
-
 
83
            case 'category':
-
 
84
                $context = \context_coursecat::instance($category->id);
-
 
85
                break;
-
 
86
 
-
 
87
            case 'system':
-
 
88
                $context = \context_system::instance();
-
 
89
                break;
-
 
90
 
88
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
91
            default:
-
 
92
                $context = \context_module::instance($quiz->cmid);
-
 
Línea 93... Línea 89...
93
                break;
89
 
Línea 94... Línea 90...
94
        }
90
        $context = \context_module::instance($quiz->cmid);
95
 
91
 
Línea 159... Línea 155...
159
        global $CFG, $DB;
155
        global $CFG, $DB;
Línea 160... Línea 156...
160
 
156
 
161
        // Set to admin user.
157
        // Set to admin user.
Línea 162... Línea 158...
162
        $this->setAdminUser();
158
        $this->setAdminUser();
163
 
159
 
164
        // Create two course categories - we are going to delete one of these later and will expect
160
        // Create 2 qbank instances - we are going to delete one of these later and will expect
-
 
161
        // all the questions belonging to the deleted module to be moved.
-
 
162
        $coursecat1 = $this->getDataGenerator()->create_category();
165
        // all the questions belonging to the course in the deleted category to be moved.
163
        $course1 = $this->getDataGenerator()->create_course(['category' => $coursecat1->id]);
-
 
164
        $modqbank1 = $this->getDataGenerator()->create_module('qbank', ['course' => $course1->id]);
-
 
165
        $coursecat2 = $this->getDataGenerator()->create_category();
Línea 166... Línea 166...
166
        $coursecat1 = $this->getDataGenerator()->create_category();
166
        $course2 = $this->getDataGenerator()->create_course(['category' => $coursecat2->id]);
167
        $coursecat2 = $this->getDataGenerator()->create_category();
167
        $modqbank2 = $this->getDataGenerator()->create_module('qbank', ['course' => $course2->id]);
168
 
168
 
169
        // Create a couple of categories and questions.
169
        // Create a couple of categories and questions.
170
        $context1 = \context_coursecat::instance($coursecat1->id);
170
        $context1 = \context_module::instance($modqbank1->cmid);
171
        $context2 = \context_coursecat::instance($coursecat2->id);
171
        $context2 = \context_module::instance($modqbank2->cmid);
172
        /** @var \core_question_generator $questiongenerator */
-
 
173
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
172
        /** @var \core_question_generator $questiongenerator */
174
        $questioncat1 = $questiongenerator->create_question_category(array('contextid' =>
-
 
175
            $context1->id));
173
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
176
        $questioncat2 = $questiongenerator->create_question_category(array('contextid' =>
174
        $questioncat1 = question_get_default_category($context1->id);
177
            $context2->id));
175
        $questioncat2 = question_get_default_category($context2->id);
178
        $question1 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat1->id));
176
        $question1 = $questiongenerator->create_question('shortanswer', null, ['category' => $questioncat1->id]);
Línea 179... Línea 177...
179
        $question2 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat1->id));
177
        $question2 = $questiongenerator->create_question('shortanswer', null, ['category' => $questioncat1->id]);
180
        $question3 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat2->id));
178
        $question3 = $questiongenerator->create_question('shortanswer', null, ['category' => $questioncat2->id]);
181
        $question4 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat2->id));
179
        $question4 = $questiongenerator->create_question('shortanswer', null, ['category' => $questioncat2->id]);
182
 
180
 
183
        // Now lets tag these questions.
181
        // Now lets tag these questions.
184
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $context1, array('tag 1', 'tag 2'));
-
 
185
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $context1, array('tag 3', 'tag 4'));
-
 
186
        \core_tag_tag::set_item_tags('core_question', 'question', $question3->id, $context2, array('tag 5', 'tag 6'));
-
 
187
        \core_tag_tag::set_item_tags('core_question', 'question', $question4->id, $context2, array('tag 7', 'tag 8'));
-
 
188
 
-
 
189
        // Test moving the questions to another category.
-
 
190
        question_move_questions_to_category(array($question1->id, $question2->id), $questioncat2->id);
-
 
191
 
-
 
192
        // Test that all tag_instances belong to one context.
-
 
193
        $this->assertEquals(8, $DB->count_records('tag_instance', array('component' => 'core_question',
-
 
194
            'contextid' => $questioncat2->contextid)));
-
 
195
 
-
 
196
        // Test moving them back.
-
 
197
        question_move_questions_to_category(array($question1->id, $question2->id), $questioncat1->id);
-
 
198
 
-
 
199
        // Test that all tag_instances are now reset to how they were initially.
-
 
Línea 200... Línea 182...
200
        $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question',
182
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $context1, ['tag 1', 'tag 2']);
201
            'contextid' => $questioncat1->contextid)));
183
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $context1, ['tag 3', 'tag 4']);
Línea 202... Línea 184...
202
        $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question',
184
        \core_tag_tag::set_item_tags('core_question', 'question', $question3->id, $context2, ['tag 5', 'tag 6']);
203
            'contextid' => $questioncat2->contextid)));
185
        \core_tag_tag::set_item_tags('core_question', 'question', $question4->id, $context2, ['tag 7', 'tag 8']);
204
 
186
 
Línea 205... Línea 187...
205
        // Now test moving a whole question category to another context.
187
        // Test moving a whole question category to another context.
206
        question_move_category_to_context($questioncat1->id, $questioncat1->contextid, $questioncat2->contextid);
188
        question_move_category_to_context($questioncat1->id, $questioncat1->contextid, $questioncat2->contextid);
207
 
189
 
Línea 208... Línea 190...
208
        // Test that all tag_instances belong to one context.
190
        // Test that all tag_instances belong to one context.
209
        $this->assertEquals(8, $DB->count_records('tag_instance', array('component' => 'core_question',
191
        $this->assertEquals(8, $DB->count_records('tag_instance', ['component' => 'core_question',
210
            'contextid' => $questioncat2->contextid)));
192
            'contextid' => $questioncat2->contextid]));
211
 
193
 
212
        // Now test moving them back.
-
 
213
        question_move_category_to_context($questioncat1->id, $questioncat2->contextid,
-
 
214
            \context_coursecat::instance($coursecat1->id)->id);
-
 
215
 
-
 
216
        // Test that all tag_instances are now reset to how they were initially.
-
 
217
        $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question',
-
 
218
            'contextid' => $questioncat1->contextid)));
-
 
219
        $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question',
194
        // Now test moving them back.
Línea 220... Línea 195...
220
            'contextid' => $questioncat2->contextid)));
195
        question_move_category_to_context($questioncat1->id, $questioncat2->contextid,
221
 
196
            \context_module::instance($modqbank1->cmid)->id);
-
 
197
 
Línea 222... Línea 198...
222
        // Now we want to test deleting the course category and moving the questions to another category.
198
        // Test that all tag_instances are now reset to how they were initially.
223
        question_delete_course_category($coursecat1, $coursecat2);
199
        $this->assertEquals(4, $DB->count_records('tag_instance', ['component' => 'core_question',
224
 
200
            'contextid' => $questioncat1->contextid]));
225
        // Test that all tag_instances belong to one context.
201
        $this->assertEquals(4, $DB->count_records('tag_instance', ['component' => 'core_question',
226
        $this->assertEquals(8, $DB->count_records('tag_instance', array('component' => 'core_question',
202
            'contextid' => $questioncat2->contextid]));
Línea 227... Línea 203...
227
            'contextid' => $questioncat2->contextid)));
203
 
228
 
204
        // Create a course.
229
        // Create a course.
205
        $course = $this->getDataGenerator()->create_course();
Línea 230... Línea 206...
230
        $course = $this->getDataGenerator()->create_course();
206
        $modqbank3 = $this->getDataGenerator()->create_module('qbank', ['course' => $course->id]);
231
 
207
 
Línea 232... Línea 208...
232
        // Create some question categories and questions in this course.
208
        // Create some question categories and questions in this course.
Línea 257... Línea 233...
257
        $rc = new \restore_controller('test-restore-course', $course2->id, \backup::INTERACTIVE_NO,
233
        $rc = new \restore_controller('test-restore-course', $course2->id, \backup::INTERACTIVE_NO,
258
            \backup::MODE_GENERAL, 2, \backup::TARGET_NEW_COURSE);
234
            \backup::MODE_GENERAL, 2, \backup::TARGET_NEW_COURSE);
259
        $rc->execute_precheck();
235
        $rc->execute_precheck();
260
        $rc->execute_plan();
236
        $rc->execute_plan();
Línea -... Línea 237...
-
 
237
 
-
 
238
        $modinfo = get_fast_modinfo($course2);
-
 
239
        $qbanks = $modinfo->get_instances_of('qbank');
-
 
240
        $qbankids = array_column($qbanks, 'instance');
-
 
241
        $qbankrecords = $DB->get_records_list('qbank', 'id', $qbankids, '', 'id, type');
-
 
242
        $qbanks = array_filter($qbanks, static function($bank) use ($qbankrecords) {
-
 
243
            if (isset($qbankrecords[$bank->instance])) {
-
 
244
                return $qbankrecords[$bank->instance]->type === question_bank_helper::TYPE_STANDARD;
-
 
245
            }
-
 
246
            return false;
-
 
247
        });
-
 
248
        $qbank = reset($qbanks);
261
 
249
 
262
        // Get the created question category.
250
        // Get the created question category.
263
        $restoredcategory = $DB->get_record_select('question_categories', 'contextid = ? AND parent <> 0',
251
        $restoredcategory = $DB->get_record_select('question_categories', 'contextid = ? AND parent <> 0',
Línea 264... Línea 252...
264
                array(\context_course::instance($course2->id)->id), '*', MUST_EXIST);
252
                [$qbank->context->id, '*', MUST_EXIST]);
265
 
253
 
266
        // Check that there are two questions in the restored to course's context.
254
        // Check that there are two questions in the restored to course's context.
267
        $this->assertEquals(2, $DB->get_record_sql('SELECT COUNT(q.id) as questioncount
255
        $this->assertEquals(2, $DB->get_record_sql('SELECT COUNT(q.id) as questioncount
Línea 280... Línea 268...
280
     */
268
     */
281
    public function test_question_delete_question(): void {
269
    public function test_question_delete_question(): void {
282
        global $DB;
270
        global $DB;
Línea 283... Línea 271...
283
 
271
 
284
        // Setup.
272
        // Setup.
285
        $context = \context_system::instance();
273
        $context = $this->create_course_and_question_bank();
286
        /** @var \core_question_generator $qgen */
274
        /** @var \core_question_generator $qgen */
287
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
275
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
288
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
276
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
289
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
277
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
Línea 303... Línea 291...
303
     */
291
     */
304
    public function test_question_delete_question_broken_data(): void {
292
    public function test_question_delete_question_broken_data(): void {
305
        global $DB;
293
        global $DB;
Línea 306... Línea 294...
306
 
294
 
307
        // Setup.
295
        // Setup.
308
        $context = \context_system::instance();
296
        $context = $this->create_course_and_question_bank();
309
        /** @var \core_question_generator $qgen */
297
        /** @var \core_question_generator $qgen */
310
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
298
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
311
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
299
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
Línea 330... Línea 318...
330
     * Test deleting a broken question whose category refers to a missing context
318
     * Test deleting a broken question whose category refers to a missing context
331
     */
319
     */
332
    public function test_question_delete_question_missing_context(): void {
320
    public function test_question_delete_question_missing_context(): void {
333
        global $DB;
321
        global $DB;
Línea 334... Línea -...
334
 
-
 
335
        $coursecategory = $this->getDataGenerator()->create_category();
322
 
Línea 336... Línea 323...
336
        $context = $coursecategory->get_context();
323
        $context = $this->create_course_and_question_bank();
337
 
324
 
338
        /** @var \core_question_generator $generator */
325
        /** @var \core_question_generator $generator */
339
        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
326
        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
Línea 352... Línea 339...
352
            'files, tags, are not cleaned up.');
339
            'files, tags, are not cleaned up.');
353
        $this->assertFalse($DB->record_exists('question', ['id' => $question->id]));
340
        $this->assertFalse($DB->record_exists('question', ['id' => $question->id]));
354
    }
341
    }
Línea 355... Línea 342...
355
 
342
 
-
 
343
    /**
-
 
344
     * Test parameters for calling question_category_delete_safe
-
 
345
     *
-
 
346
     * @return array
-
 
347
     */
-
 
348
    public static function delete_category_parameters(): array {
-
 
349
        return [
-
 
350
            'Delete category' => [
-
 
351
                'coursedeletion' => false,
-
 
352
            ],
-
 
353
            'Delete category with course' => [
-
 
354
                'coursedeletion' => true,
-
 
355
            ],
-
 
356
        ];
-
 
357
    }
-
 
358
 
356
    /**
359
    /**
-
 
360
     * This function tests the question_category_delete_safe function.
-
 
361
     *
-
 
362
     * @param bool $coursedeletion If true, simulate calling question_category_delete_safe as part of deletion of the whole course.
-
 
363
     * @dataProvider delete_category_parameters
357
     * This function tests the question_category_delete_safe function.
364
     * @covers ::question_category_delete_safe
358
     */
365
     */
359
    public function test_question_category_delete_safe(): void {
366
    public function test_question_category_delete_safe(bool $coursedeletion): void {
360
        global $DB;
367
        global $DB;
361
        $this->resetAfterTest(true);
368
        $this->resetAfterTest(true);
Línea 362... Línea 369...
362
        $this->setAdminUser();
369
        $this->setAdminUser();
-
 
370
 
-
 
371
        [, $course, , $qcat, $questions] = $this->setup_quiz_and_questions();
Línea 363... Línea 372...
363
 
372
 
Línea 364... Línea 373...
364
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions();
373
        $targetcourseid = $coursedeletion ? SITEID : $course->id;
365
 
374
 
366
        question_category_delete_safe($qcat);
375
        question_category_delete_safe($qcat, $coursedeletion);
Línea 367... Línea 376...
367
 
376
 
368
        // Verify category deleted.
377
        // Verify category deleted.
Línea 369... Línea 378...
369
        $criteria = array('id' => $qcat->id);
378
        $criteria = ['id' => $qcat->id];
370
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
379
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
-
 
380
 
-
 
381
        // Verify questions deleted or moved.
-
 
382
        $this->assert_category_contains_questions($qcat->id, 0);
-
 
383
 
-
 
384
        // Verify question not deleted.
-
 
385
        $criteria = ['id' => $questions[0]->id];
-
 
386
        $savedquestion = $DB->get_record_sql(
-
 
387
            "SELECT q.*, qbe.questioncategoryid
-
 
388
               FROM {question} q
-
 
389
                    JOIN {question_versions} qv ON qv.questionid = q.id
371
 
390
                    JOIN {question_bank_entries} qbe ON qv.questionbankentryid = qbe.id",
-
 
391
            $criteria
-
 
392
        );
-
 
393
        $this->assertNotEmpty($savedquestion);
-
 
394
 
-
 
395
        // Verify question now sits in a system qbank in the target course.
-
 
396
        $this->assertNotEquals($qcat->id, $savedquestion->id);
-
 
397
        $newcategory = $DB->get_record('question_categories', ['id' => $savedquestion->questioncategoryid], strictness: MUST_EXIST);
372
        // Verify questions deleted or moved.
398
        $newcategorycontext = context::instance_by_id($newcategory->contextid);
Línea 373... Línea 399...
373
        $this->assert_category_contains_questions($qcat->id, 0);
399
        $this->assertEquals(\context_module::LEVEL, $newcategorycontext->contextlevel);
374
 
400
        [$newcourse, $newcm] = get_course_and_cm_from_cmid($newcategorycontext->instanceid);
375
        // Verify question not deleted.
401
        $this->assertEquals($newcm->modname, 'qbank');
Línea 400... Línea 426...
400
        $this->assert_category_contains_questions($qcat->id, 0);
426
        $this->assert_category_contains_questions($qcat->id, 0);
401
    }
427
    }
Línea 402... Línea 428...
402
 
428
 
403
    /**
429
    /**
-
 
430
     * This function tests the question_delete_context function.
-
 
431
     *
404
     * This function tests the question_delete_context function.
432
     * @covers ::question_delete_context()
405
     */
433
     */
406
    public function test_question_delete_context(): void {
434
    public function test_question_delete_context(): void {
407
        global $DB;
435
        global $DB;
408
        $this->resetAfterTest(true);
436
        $this->resetAfterTest(true);
Línea 412... Línea 440...
412
 
440
 
413
        // Get the module context id.
441
        // Get the module context id.
Línea 414... Línea 442...
414
        $result = question_delete_context($qcat->contextid);
442
        $result = question_delete_context($qcat->contextid);
415
 
443
 
416
        // Verify category deleted.
-
 
417
        $criteria = array('id' => $qcat->id);
-
 
418
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
-
 
419
 
-
 
420
        // Verify questions deleted or moved.
-
 
421
        $this->assert_category_contains_questions($qcat->id, 0);
-
 
422
    }
-
 
423
 
-
 
424
    /**
-
 
425
     * This function tests the question_delete_course function.
-
 
426
     */
-
 
427
    public function test_question_delete_course(): void {
-
 
428
        global $DB;
-
 
429
        $this->resetAfterTest(true);
-
 
430
        $this->setAdminUser();
-
 
431
 
-
 
432
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
-
 
433
 
-
 
434
        // Test the deletion.
-
 
435
        question_delete_course($course);
-
 
436
 
-
 
437
        // Verify category deleted.
444
        // Verify category deleted.
Línea 438... Línea 445...
438
        $criteria = array('id' => $qcat->id);
445
        $criteria = ['id' => $qcat->id];
439
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
446
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
440
 
447
 
Línea 441... Línea 448...
441
        // Verify questions deleted or moved.
448
        // Verify questions deleted or moved.
442
        $this->assert_category_contains_questions($qcat->id, 0);
-
 
443
    }
-
 
444
 
-
 
445
    /**
-
 
446
     * This function tests the question_delete_course_category function.
-
 
447
     */
-
 
448
    public function test_question_delete_course_category(): void {
-
 
449
        global $DB;
-
 
450
        $this->resetAfterTest(true);
-
 
451
        $this->setAdminUser();
-
 
452
 
-
 
453
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
454
 
-
 
455
        // Test that the feedback works.
-
 
456
        question_delete_course_category($category, null);
-
 
457
 
-
 
458
        // Verify category deleted.
-
 
459
        $criteria = array('id' => $qcat->id);
-
 
460
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
-
 
461
 
-
 
462
        // Verify questions deleted or moved.
-
 
463
        $this->assert_category_contains_questions($qcat->id, 0);
-
 
464
    }
-
 
465
 
-
 
466
    /**
-
 
467
     * This function tests the question_delete_course_category function when it is supposed to move question categories.
-
 
468
     */
-
 
469
    public function test_question_delete_course_category_move_qcats(): void {
-
 
470
        global $DB;
-
 
471
        $this->resetAfterTest(true);
-
 
472
        $this->setAdminUser();
-
 
473
 
-
 
474
        list($category1, $course1, $quiz1, $qcat1, $questions1) = $this->setup_quiz_and_questions('category');
-
 
475
        list($category2, $course2, $quiz2, $qcat2, $questions2) = $this->setup_quiz_and_questions('category');
-
 
476
 
-
 
477
        $questionsinqcat1 = count($questions1);
-
 
478
        $questionsinqcat2 = count($questions2);
-
 
479
 
-
 
480
        // Test the delete.
-
 
481
        question_delete_course_category($category1, $category2);
-
 
482
 
-
 
483
        // Verify category not deleted.
-
 
484
        $criteria = array('id' => $qcat1->id);
-
 
485
        $this->assertEquals(1, $DB->count_records('question_categories', $criteria));
-
 
486
 
-
 
487
        // Verify questions are moved.
-
 
488
        $params = array($qcat2->contextid);
-
 
489
        $actualquestionscount = $DB->count_records_sql("SELECT COUNT(*)
-
 
490
                                                              FROM {question} q
-
 
491
                                                              JOIN {question_versions} qv ON qv.questionid = q.id
-
 
492
                                                              JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
-
 
493
                                                              JOIN {question_categories} qc ON qc.id = qbe.questioncategoryid
-
 
494
                                                             WHERE qc.contextid = ?", $params);
-
 
495
        $this->assertEquals($questionsinqcat1 + $questionsinqcat2, $actualquestionscount);
-
 
496
 
-
 
497
        // Verify there is just a single top-level category.
-
 
498
        $criteria = array('contextid' => $qcat2->contextid, 'parent' => 0);
-
 
499
        $this->assertEquals(1, $DB->count_records('question_categories', $criteria));
-
 
500
 
-
 
501
        // Verify there is no question category in previous context.
-
 
502
        $criteria = array('contextid' => $qcat1->contextid);
-
 
503
        $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
449
        $this->assert_category_contains_questions($qcat->id, 0);
504
    }
450
    }
-
 
451
 
-
 
452
    /**
505
 
453
     * This function tests the question_save_from_deletion function when it is supposed to make a new category and
506
    /**
454
     * move question categories to that new category.
507
     * This function tests the question_save_from_deletion function when it is supposed to make a new category and
455
     *
508
     * move question categories to that new category.
456
     * @covers ::question_save_from_deletion()
509
     */
457
     */
Línea 510... Línea 458...
510
    public function test_question_save_from_deletion(): void {
458
    public function test_question_save_from_deletion(): void {
-
 
459
        global $DB;
-
 
460
        $this->resetAfterTest(true);
Línea 511... Línea 461...
511
        global $DB;
461
        $this->setAdminUser();
Línea 512... Línea 462...
512
        $this->resetAfterTest(true);
462
 
513
        $this->setAdminUser();
-
 
Línea 514... Línea 463...
514
 
463
        [$category, $course, $quiz, $qcat, $questions] = $this->setup_quiz_and_questions();
515
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions();
464
        $qbank = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
Línea 516... Línea 465...
516
 
465
        $qbankcontext = \context_module::instance($qbank->cmid);
Línea 527... Línea 476...
527
    }
476
    }
Línea 528... Línea 477...
528
 
477
 
529
    /**
478
    /**
530
     * This function tests the question_save_from_deletion function when it is supposed to make a new category and
479
     * This function tests the question_save_from_deletion function when it is supposed to make a new category and
-
 
480
     * move question categories to that new category when quiz name is very long but less than 256 characters.
-
 
481
     *
531
     * move question categories to that new category when quiz name is very long but less than 256 characters.
482
     * @covers ::question_save_from_deletion()
532
     */
483
     */
533
    public function test_question_save_from_deletion_quiz_with_long_name(): void {
484
    public function test_question_save_from_deletion_quiz_with_long_name(): void {
534
        global $DB;
485
        global $DB;
535
        $this->resetAfterTest(true);
486
        $this->resetAfterTest(true);
Línea 536... Línea 487...
536
        $this->setAdminUser();
487
        $this->setAdminUser();
-
 
488
 
-
 
489
        [$category, $course, $quiz, $qcat, $questions] = $this->setup_quiz_and_questions();
Línea 537... Línea 490...
537
 
490
        $qbank = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
538
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions();
491
        $qbankcontext = \context_module::instance($qbank->cmid);
Línea 539... Línea 492...
539
 
492
 
Línea 540... Línea 493...
540
        // Moodle doesn't allow you to enter a name longer than 255 characters.
493
        // Moodle doesn't allow you to enter a name longer than 255 characters.
Línea 541... Línea 494...
541
        $quiz->name = shorten_text(str_repeat('123456789 ', 26), 255);
494
        $quiz->name = shorten_text(str_repeat('123456789 ', 26), 255);
542
 
-
 
Línea 543... Línea 495...
543
        $DB->update_record('quiz', $quiz);
495
 
544
 
496
        $DB->update_record('quiz', $quiz);
Línea 545... Línea 497...
545
        $context = \context::instance_by_id($qcat->contextid);
497
 
Línea 557... Línea 509...
557
        $this->assertEquals(1, $DB->count_records('question_categories', ['contextid' => $qcat->contextid, 'parent' => 0]));
509
        $this->assertEquals(1, $DB->count_records('question_categories', ['contextid' => $qcat->contextid, 'parent' => 0]));
558
    }
510
    }
Línea 559... Línea 511...
559
 
511
 
560
    /**
512
    /**
-
 
513
     * get_question_options should add the category object to the given question.
-
 
514
     *
561
     * get_question_options should add the category object to the given question.
515
     * @covers ::get_question_options()
562
     */
516
     */
563
    public function test_get_question_options_includes_category_object_single_question(): void {
517
    public function test_get_question_options_includes_category_object_single_question(): void {
564
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
518
        [$category, $course, $quiz, $qcat, $questions] = $this->setup_quiz_and_questions();
Línea 565... Línea 519...
565
        $question = array_shift($questions);
519
        $question = array_shift($questions);
Línea 566... Línea 520...
566
 
520
 
567
        get_question_options($question);
521
        get_question_options($question);
Línea 568... Línea 522...
568
 
522
 
569
        $this->assertEquals($qcat, $question->categoryobject);
523
        $this->assertEquals($qcat, $question->categoryobject);
570
    }
524
    }
-
 
525
 
-
 
526
    /**
571
 
527
     * get_question_options should add the category object to all of the questions in
572
    /**
528
     * the given list.
573
     * get_question_options should add the category object to all of the questions in
529
     *
Línea 574... Línea 530...
574
     * the given list.
530
     * @covers ::get_question_options()
Línea 575... Línea 531...
575
     */
531
     */
576
    public function test_get_question_options_includes_category_object_multiple_questions(): void {
532
    public function test_get_question_options_includes_category_object_multiple_questions(): void {
577
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
533
        [$category, $course, $quiz, $qcat, $questions] = $this->setup_quiz_and_questions();
578
 
534
 
Línea 579... Línea 535...
579
        get_question_options($questions);
535
        get_question_options($questions);
580
 
536
 
-
 
537
        foreach ($questions as $question) {
-
 
538
            $this->assertEquals($qcat, $question->categoryobject);
581
        foreach ($questions as $question) {
539
        }
582
            $this->assertEquals($qcat, $question->categoryobject);
540
    }
583
        }
541
 
584
    }
542
    /**
585
 
543
     * get_question_options includes the tags for all questions in the list.
586
    /**
544
     *
Línea 587... Línea 545...
587
     * get_question_options includes the tags for all questions in the list.
545
     * @covers ::get_question_options()
Línea 613... Línea 571...
613
            sort($tags);
571
            sort($tags);
614
            sort($actualtagobjects);
572
            sort($actualtagobjects);
Línea 615... Línea 573...
615
 
573
 
616
            // The question should have a full set of each tag object.
574
            // The question should have a full set of each tag object.
617
            $this->assertEquals($tags, $actualtagobjects);
-
 
618
            // The question should not have any course tags.
-
 
619
            $this->assertEmpty($question->coursetagobjects);
-
 
620
        }
-
 
621
    }
-
 
622
 
-
 
623
    /**
-
 
624
     * get_question_options includes the course tags for all questions in the list.
-
 
625
     */
-
 
626
    public function test_get_question_options_includes_course_tags(): void {
-
 
627
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
628
        $question1 = $questions[0];
-
 
629
        $question2 = $questions[1];
-
 
630
        $coursecontext = \context_course::instance($course->id);
-
 
631
 
-
 
632
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo', 'bar']);
-
 
633
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['baz', 'bop']);
-
 
634
 
-
 
635
        get_question_options($questions, true);
-
 
636
 
-
 
637
        foreach ($questions as $question) {
-
 
638
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
639
            $expectedcoursetags = [];
-
 
640
            $actualcoursetags = $question->coursetags;
-
 
641
            foreach ($tags as $tag) {
-
 
642
                $expectedcoursetags[$tag->id] = $tag->get_display_name();
-
 
643
            }
-
 
644
 
-
 
645
            // The question should have a coursetags property populated with each tag id
-
 
646
            // and display name as a key vale pair.
-
 
647
            $this->assertEquals($expectedcoursetags, $actualcoursetags);
-
 
648
 
-
 
649
            $actualcoursetagobjects = $question->coursetagobjects;
-
 
650
            sort($tags);
-
 
651
            sort($actualcoursetagobjects);
-
 
652
 
-
 
653
            // The question should have a full set of the course tag objects.
-
 
654
            $this->assertEquals($tags, $actualcoursetagobjects);
-
 
655
            // The question should not have any other tags.
-
 
656
            $this->assertEmpty($question->tagobjects);
-
 
657
            $this->assertEmpty($question->tags);
-
 
658
        }
-
 
659
    }
-
 
660
 
-
 
661
    /**
-
 
662
     * get_question_options only categorises a tag as a course tag if it is in a
-
 
663
     * course context that is different from the question context.
-
 
664
     */
-
 
665
    public function test_get_question_options_course_tags_in_course_question_context(): void {
-
 
666
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
-
 
667
        $question1 = $questions[0];
-
 
668
        $question2 = $questions[1];
-
 
669
        $coursecontext = \context_course::instance($course->id);
-
 
670
 
-
 
671
        // Create course level tags in the course context that matches the question
-
 
672
        // course context.
-
 
673
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo', 'bar']);
-
 
674
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['baz', 'bop']);
-
 
675
 
-
 
676
        get_question_options($questions, true);
-
 
677
 
-
 
678
        foreach ($questions as $question) {
-
 
679
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
680
 
-
 
681
            $actualtagobjects = $question->tagobjects;
-
 
682
            sort($tags);
-
 
683
            sort($actualtagobjects);
-
 
684
 
-
 
685
            // The tags should not be considered course tags because they are in
-
 
686
            // the same context as the question. That makes them question tags.
-
 
687
            $this->assertEmpty($question->coursetagobjects);
-
 
688
            // The course context tags should be returned in the regular tag object
-
 
689
            // list.
-
 
690
            $this->assertEquals($tags, $actualtagobjects);
-
 
691
        }
-
 
692
    }
-
 
693
 
-
 
694
    /**
-
 
695
     * get_question_options includes the tags and course tags for all questions in the list
-
 
696
     * if each question has course and question level tags.
-
 
697
     */
-
 
698
    public function test_get_question_options_includes_question_and_course_tags(): void {
-
 
699
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
700
        $question1 = $questions[0];
-
 
701
        $question2 = $questions[1];
-
 
702
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
703
        $coursecontext = \context_course::instance($course->id);
-
 
704
 
-
 
705
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo', 'bar']);
-
 
706
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['cfoo', 'cbar']);
-
 
707
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['baz', 'bop']);
-
 
708
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['cbaz', 'cbop']);
-
 
709
 
-
 
710
        get_question_options($questions, true);
-
 
711
 
-
 
712
        foreach ($questions as $question) {
-
 
713
            $alltags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
714
            $tags = array_filter($alltags, function($tag) use ($qcontext) {
-
 
715
                return $tag->taginstancecontextid == $qcontext->id;
-
 
716
            });
-
 
717
            $coursetags = array_filter($alltags, function($tag) use ($coursecontext) {
-
 
718
                return $tag->taginstancecontextid == $coursecontext->id;
-
 
719
            });
-
 
720
 
-
 
721
            $expectedtags = [];
-
 
722
            $actualtags = $question->tags;
-
 
723
            foreach ($tags as $tag) {
-
 
724
                $expectedtags[$tag->id] = $tag->get_display_name();
-
 
725
            }
-
 
726
 
-
 
727
            // The question should have a tags property populated with each tag id
-
 
728
            // and display name as a key vale pair.
-
 
729
            $this->assertEquals($expectedtags, $actualtags);
-
 
730
 
-
 
731
            $actualtagobjects = $question->tagobjects;
-
 
732
            sort($tags);
-
 
733
            sort($actualtagobjects);
-
 
734
            // The question should have a full set of each tag object.
-
 
735
            $this->assertEquals($tags, $actualtagobjects);
-
 
736
 
-
 
737
            $actualcoursetagobjects = $question->coursetagobjects;
-
 
738
            sort($coursetags);
-
 
739
            sort($actualcoursetagobjects);
-
 
740
            // The question should have a full set of course tag objects.
-
 
741
            $this->assertEquals($coursetags, $actualcoursetagobjects);
575
            $this->assertEquals($tags, $actualtagobjects);
742
        }
576
        }
Línea 743... Línea 577...
743
    }
577
    }
744
 
578
 
745
    /**
579
    /**
746
     * get_question_options should update the context id to the question category
580
     * get_question_options should update the context id to the question category
-
 
581
     * context id for any non-course context tag that isn't in the question category
-
 
582
     * context.
747
     * context id for any non-course context tag that isn't in the question category
583
     *
748
     * context.
584
     * @covers ::get_question_options()
749
     */
585
     */
750
    public function test_get_question_options_normalises_question_tags(): void {
586
    public function test_get_question_options_normalises_question_tags(): void {
751
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
587
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions();
752
        $question1 = $questions[0];
588
        $question1 = $questions[0];
753
        $question2 = $questions[1];
589
        $question2 = $questions[1];
Línea 784... Línea 620...
784
            }
620
            }
785
        }
621
        }
786
    }
622
    }
Línea 787... Línea 623...
787
 
623
 
788
    /**
-
 
789
     * get_question_options if the question is a course level question then tags
-
 
790
     * in that context should not be consdered course tags, they are question tags.
-
 
791
     */
-
 
792
    public function test_get_question_options_includes_course_context_question_tags(): void {
-
 
793
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
-
 
794
        $question1 = $questions[0];
-
 
795
        $question2 = $questions[1];
-
 
796
        $coursecontext = \context_course::instance($course->id);
-
 
797
 
-
 
798
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo', 'bar']);
-
 
799
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['baz', 'bop']);
-
 
800
 
-
 
801
        get_question_options($questions, true);
-
 
802
 
-
 
803
        foreach ($questions as $question) {
-
 
804
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
805
            // Tags in a course context that matches the question context should
-
 
806
            // not be considered course tags.
-
 
807
            $this->assertEmpty($question->coursetagobjects);
-
 
808
            $this->assertEmpty($question->coursetags);
-
 
809
 
-
 
810
            $actualtagobjects = $question->tagobjects;
-
 
811
            sort($tags);
-
 
812
            sort($actualtagobjects);
-
 
813
            // The tags should be considered question tags not course tags.
-
 
814
            $this->assertEquals($tags, $actualtagobjects);
-
 
815
        }
-
 
816
    }
-
 
817
 
-
 
818
    /**
-
 
819
     * get_question_options should return tags from all course contexts by default.
-
 
820
     */
-
 
821
    public function test_get_question_options_includes_multiple_courses_tags(): void {
-
 
822
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
823
        $question1 = $questions[0];
-
 
824
        $question2 = $questions[1];
-
 
825
        $coursecontext = \context_course::instance($course->id);
-
 
826
        // Create a sibling course.
-
 
827
        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
-
 
828
        $siblingcoursecontext = \context_course::instance($siblingcourse->id);
-
 
829
 
-
 
830
        // Create course tags.
-
 
831
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['c1']);
-
 
832
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['c1']);
-
 
833
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['c2']);
-
 
834
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['c2']);
-
 
835
 
-
 
836
        get_question_options($questions, true);
-
 
837
 
-
 
838
        foreach ($questions as $question) {
-
 
839
            $this->assertCount(2, $question->coursetagobjects);
-
 
840
 
-
 
841
            foreach ($question->coursetagobjects as $tag) {
-
 
842
                if ($tag->name == 'c1') {
-
 
843
                    $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
844
                } else {
-
 
845
                    $this->assertEquals($siblingcoursecontext->id, $tag->taginstancecontextid);
-
 
846
                }
-
 
847
            }
-
 
848
        }
-
 
849
    }
-
 
850
 
-
 
851
    /**
-
 
852
     * get_question_options should filter the course tags by the given list of courses.
-
 
853
     */
-
 
854
    public function test_get_question_options_includes_filter_course_tags(): void {
-
 
855
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
856
        $question1 = $questions[0];
-
 
857
        $question2 = $questions[1];
-
 
858
        $coursecontext = \context_course::instance($course->id);
-
 
859
        // Create a sibling course.
-
 
860
        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
-
 
861
        $siblingcoursecontext = \context_course::instance($siblingcourse->id);
-
 
862
 
-
 
863
        // Create course tags.
-
 
864
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo']);
-
 
865
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['bar']);
-
 
866
        // Create sibling course tags. These should be filtered out.
-
 
867
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['filtered1']);
-
 
868
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['filtered2']);
-
 
869
 
-
 
870
        // Ask to only receive course tags from $course (ignoring $siblingcourse tags).
-
 
871
        get_question_options($questions, true, [$course]);
-
 
872
 
-
 
873
        foreach ($questions as $question) {
-
 
874
            foreach ($question->coursetagobjects as $tag) {
-
 
875
                // We should only be seeing course tags from $course. The tags from
-
 
876
                // $siblingcourse should have been filtered out.
-
 
877
                $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
878
            }
-
 
879
        }
-
 
880
    }
-
 
881
 
-
 
882
    /**
-
 
883
     * question_move_question_tags_to_new_context should update all of the
-
 
884
     * question tags contexts when they are moving down (from system to course
-
 
885
     * category context).
-
 
886
     */
-
 
887
    public function test_question_move_question_tags_to_new_context_system_to_course_cat_qtags(): void {
-
 
888
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
-
 
889
        $question1 = $questions[0];
-
 
890
        $question2 = $questions[1];
-
 
891
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
892
        $newcontext = \context_coursecat::instance($category->id);
-
 
893
 
-
 
894
        foreach ($questions as $question) {
-
 
895
            $question->contextid = $qcat->contextid;
-
 
896
        }
-
 
897
 
-
 
898
        // Create tags in the system context.
-
 
899
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo', 'bar']);
-
 
900
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo', 'bar']);
-
 
901
 
-
 
902
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
903
 
-
 
904
        foreach ($questions as $question) {
-
 
905
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
906
 
-
 
907
            // All of the tags should have their context id set to the new context.
-
 
908
            foreach ($tags as $tag) {
-
 
909
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
910
            }
-
 
911
        }
-
 
912
    }
-
 
913
 
-
 
914
    /**
-
 
915
     * question_move_question_tags_to_new_context should update all of the question tags
-
 
916
     * contexts when they are moving down (from system to course category context)
-
 
917
     * but leave any tags in the course context where they are.
-
 
918
     */
-
 
919
    public function test_question_move_question_tags_to_new_context_system_to_course_cat_qtags_and_course_tags(): void {
-
 
920
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
-
 
921
        $question1 = $questions[0];
-
 
922
        $question2 = $questions[1];
-
 
923
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
924
        $coursecontext = \context_course::instance($course->id);
-
 
925
        $newcontext = \context_coursecat::instance($category->id);
-
 
926
 
-
 
927
        foreach ($questions as $question) {
-
 
928
            $question->contextid = $qcat->contextid;
-
 
929
        }
-
 
930
 
-
 
931
        // Create tags in the system context.
-
 
932
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
933
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
934
        // Create tags in the course context.
-
 
935
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
-
 
936
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
-
 
937
 
-
 
938
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
939
 
-
 
940
        foreach ($questions as $question) {
-
 
941
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
942
 
-
 
943
            foreach ($tags as $tag) {
-
 
944
                if ($tag->name == 'ctag') {
-
 
945
                    // Course tags should remain in the course context.
-
 
946
                    $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
947
                } else {
-
 
948
                    // Other tags should be updated.
-
 
949
                    $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
950
                }
-
 
951
            }
-
 
952
        }
-
 
953
    }
-
 
954
 
-
 
955
    /**
-
 
956
     * question_move_question_tags_to_new_context should update all of the question
-
 
957
     * contexts tags when they are moving up (from course category to system context).
-
 
958
     */
-
 
959
    public function test_question_move_question_tags_to_new_context_course_cat_to_system_qtags(): void {
-
 
960
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
961
        $question1 = $questions[0];
-
 
962
        $question2 = $questions[1];
-
 
963
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
964
        $newcontext = \context_system::instance();
-
 
965
 
-
 
966
        foreach ($questions as $question) {
-
 
967
            $question->contextid = $qcat->contextid;
-
 
968
        }
-
 
969
 
-
 
970
        // Create tags in the course category context.
-
 
971
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo', 'bar']);
-
 
972
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo', 'bar']);
-
 
973
 
-
 
974
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
975
 
-
 
976
        foreach ($questions as $question) {
-
 
977
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
978
 
-
 
979
            // All of the tags should have their context id set to the new context.
-
 
980
            foreach ($tags as $tag) {
-
 
981
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
982
            }
-
 
983
        }
-
 
984
    }
-
 
985
 
-
 
986
    /**
-
 
987
     * question_move_question_tags_to_new_context should update all of the question
-
 
988
     * tags contexts when they are moving up (from course category context to system
-
 
989
     * context) but leave any tags in the course context where they are.
-
 
990
     */
-
 
991
    public function test_question_move_question_tags_to_new_context_course_cat_to_system_qtags_and_course_tags(): void {
-
 
992
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
993
        $question1 = $questions[0];
-
 
994
        $question2 = $questions[1];
-
 
995
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
996
        $coursecontext = \context_course::instance($course->id);
-
 
997
        $newcontext = \context_system::instance();
-
 
998
 
-
 
999
        foreach ($questions as $question) {
-
 
1000
            $question->contextid = $qcat->contextid;
-
 
1001
        }
-
 
1002
 
-
 
1003
        // Create tags in the system context.
-
 
1004
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1005
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1006
        // Create tags in the course context.
-
 
1007
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
-
 
1008
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
-
 
1009
 
-
 
1010
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1011
 
-
 
1012
        foreach ($questions as $question) {
-
 
1013
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1014
 
-
 
1015
            foreach ($tags as $tag) {
-
 
1016
                if ($tag->name == 'ctag') {
-
 
1017
                    // Course tags should remain in the course context.
-
 
1018
                    $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
1019
                } else {
-
 
1020
                    // Other tags should be updated.
-
 
1021
                    $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1022
                }
-
 
1023
            }
-
 
1024
        }
-
 
1025
    }
-
 
1026
 
-
 
1027
    /**
-
 
1028
     * question_move_question_tags_to_new_context should merge all tags into the course
-
 
1029
     * context when moving down from course category context into course context.
-
 
1030
     */
-
 
1031
    public function test_question_move_question_tags_to_new_context_course_cat_to_coures_qtags_and_course_tags(): void {
-
 
1032
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1033
        $question1 = $questions[0];
-
 
1034
        $question2 = $questions[1];
-
 
1035
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1036
        $coursecontext = \context_course::instance($course->id);
-
 
1037
        $newcontext = $coursecontext;
-
 
1038
 
-
 
1039
        foreach ($questions as $question) {
-
 
1040
            $question->contextid = $qcat->contextid;
-
 
1041
        }
-
 
1042
 
-
 
1043
        // Create tags in the system context.
-
 
1044
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1045
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1046
        // Create tags in the course context.
-
 
1047
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
-
 
1048
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
-
 
1049
 
-
 
1050
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1051
 
-
 
1052
        foreach ($questions as $question) {
-
 
1053
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1054
            // Each question should have 2 tags.
-
 
1055
            $this->assertCount(2, $tags);
-
 
1056
 
-
 
1057
            foreach ($tags as $tag) {
-
 
1058
                // All tags should be updated to the course context and merged in.
-
 
1059
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1060
            }
-
 
1061
        }
-
 
1062
    }
-
 
1063
 
-
 
1064
    /**
-
 
1065
     * question_move_question_tags_to_new_context should delete all of the tag
-
 
1066
     * instances from sibling courses when moving the context of a question down
-
 
1067
     * from a course category into a course context because the other courses will
-
 
1068
     * no longer have access to the question.
-
 
1069
     */
-
 
1070
    public function test_question_move_question_tags_to_new_context_remove_other_course_tags(): void {
-
 
1071
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1072
        // Create a sibling course.
-
 
1073
        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
-
 
1074
        $question1 = $questions[0];
-
 
1075
        $question2 = $questions[1];
-
 
1076
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1077
        $coursecontext = \context_course::instance($course->id);
-
 
1078
        $siblingcoursecontext = \context_course::instance($siblingcourse->id);
-
 
1079
        $newcontext = $coursecontext;
-
 
1080
 
-
 
1081
        foreach ($questions as $question) {
-
 
1082
            $question->contextid = $qcat->contextid;
-
 
1083
        }
-
 
1084
 
-
 
1085
        // Create tags in the system context.
-
 
1086
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1087
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1088
        // Create tags in the target course context.
-
 
1089
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
-
 
1090
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
-
 
1091
        // Create tags in the sibling course context. These should be deleted as
-
 
1092
        // part of the move.
-
 
1093
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['stag']);
-
 
1094
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['stag']);
-
 
1095
 
-
 
1096
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1097
 
-
 
1098
        foreach ($questions as $question) {
-
 
1099
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1100
            // Each question should have 2 tags, 'foo' and 'ctag'.
-
 
1101
            $this->assertCount(2, $tags);
-
 
1102
 
-
 
1103
            foreach ($tags as $tag) {
-
 
1104
                $tagname = $tag->name;
-
 
1105
                // The 'stag' should have been deleted because it's in a sibling
-
 
1106
                // course context.
-
 
1107
                $this->assertContains($tagname, ['foo', 'ctag']);
-
 
1108
                // All tags should be in the course context now.
-
 
1109
                $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
1110
            }
-
 
1111
        }
-
 
1112
    }
-
 
1113
 
-
 
1114
    /**
-
 
1115
     * question_move_question_tags_to_new_context should update all of the question
-
 
1116
     * tags to be the course category context when moving the tags from a course
-
 
1117
     * context to a course category context.
-
 
1118
     */
-
 
1119
    public function test_question_move_question_tags_to_new_context_course_to_course_cat(): void {
-
 
1120
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
-
 
1121
        $question1 = $questions[0];
-
 
1122
        $question2 = $questions[1];
-
 
1123
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1124
        // Moving up into the course category context.
-
 
1125
        $newcontext = \context_coursecat::instance($category->id);
-
 
1126
 
-
 
1127
        foreach ($questions as $question) {
-
 
1128
            $question->contextid = $qcat->contextid;
-
 
1129
        }
-
 
1130
 
-
 
1131
        // Create tags in the course context.
-
 
1132
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1133
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1134
 
-
 
1135
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1136
 
-
 
1137
        foreach ($questions as $question) {
-
 
1138
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1139
 
-
 
1140
            // All of the tags should have their context id set to the new context.
-
 
1141
            foreach ($tags as $tag) {
-
 
1142
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1143
            }
-
 
1144
        }
-
 
1145
    }
-
 
1146
 
-
 
1147
    /**
-
 
1148
     * question_move_question_tags_to_new_context should update all of the
-
 
1149
     * question tags contexts when they are moving down (from system to course
-
 
1150
     * category context).
-
 
1151
     */
-
 
1152
    public function test_question_move_question_tags_to_new_context_orphaned_tag_contexts(): void {
-
 
1153
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
-
 
1154
        $question1 = $questions[0];
-
 
1155
        $question2 = $questions[1];
-
 
1156
        $othercategory = $this->getDataGenerator()->create_category();
-
 
1157
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1158
        $newcontext = \context_coursecat::instance($category->id);
-
 
1159
        $othercategorycontext = \context_coursecat::instance($othercategory->id);
-
 
1160
 
-
 
1161
        foreach ($questions as $question) {
-
 
1162
            $question->contextid = $qcat->contextid;
-
 
1163
        }
-
 
1164
 
-
 
1165
        // Create tags in the system context.
-
 
1166
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1167
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1168
        // Create tags in the other course category context. These should be
-
 
1169
        // update to the next context id because they represent erroneous data
-
 
1170
        // from a time before context id was mandatory in the tag API.
-
 
1171
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $othercategorycontext, ['bar']);
-
 
1172
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $othercategorycontext, ['bar']);
-
 
1173
 
-
 
1174
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1175
 
-
 
1176
        foreach ($questions as $question) {
-
 
1177
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1178
            // Each question should have two tags, 'foo' and 'bar'.
-
 
1179
            $this->assertCount(2, $tags);
-
 
1180
 
-
 
1181
            // All of the tags should have their context id set to the new context
-
 
1182
            // (course category context).
-
 
1183
            foreach ($tags as $tag) {
-
 
1184
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1185
            }
-
 
1186
        }
-
 
1187
    }
-
 
1188
 
-
 
1189
    /**
624
    /**
1190
     * When moving from a course category context down into an activity context
-
 
1191
     * all question context tags and course tags (where the course is a parent of
-
 
1192
     * the activity) should move into the new context.
-
 
1193
     */
-
 
1194
    public function test_question_move_question_tags_to_new_context_course_cat_to_activity_qtags_and_course_tags(): void {
-
 
1195
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1196
        $question1 = $questions[0];
-
 
1197
        $question2 = $questions[1];
-
 
1198
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1199
        $coursecontext = \context_course::instance($course->id);
-
 
1200
        $newcontext = \context_module::instance($quiz->cmid);
-
 
1201
 
-
 
1202
        foreach ($questions as $question) {
-
 
1203
            $question->contextid = $qcat->contextid;
-
 
1204
        }
-
 
1205
 
-
 
1206
        // Create tags in the course category context.
-
 
1207
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1208
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1209
        // Move the questions to the activity context which is a child context of
-
 
1210
        // $coursecontext.
-
 
1211
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
-
 
1212
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
-
 
1213
 
-
 
1214
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1215
 
-
 
1216
        foreach ($questions as $question) {
-
 
1217
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1218
            // Each question should have 2 tags.
-
 
1219
            $this->assertCount(2, $tags);
-
 
1220
 
-
 
1221
            foreach ($tags as $tag) {
-
 
1222
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1223
            }
-
 
1224
        }
-
 
1225
    }
-
 
1226
 
-
 
1227
    /**
-
 
1228
     * When moving from a course category context down into an activity context
-
 
1229
     * all question context tags and course tags (where the course is a parent of
-
 
1230
     * the activity) should move into the new context. Tags in course contexts
-
 
1231
     * that are not a parent of the activity context should be deleted.
-
 
1232
     */
-
 
1233
    public function test_question_move_question_tags_to_new_context_course_cat_to_activity_orphaned_tags(): void {
-
 
1234
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1235
        $question1 = $questions[0];
-
 
1236
        $question2 = $questions[1];
-
 
1237
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1238
        $coursecontext = \context_course::instance($course->id);
-
 
1239
        $newcontext = \context_module::instance($quiz->cmid);
-
 
1240
        $othercourse = $this->getDataGenerator()->create_course();
-
 
1241
        $othercoursecontext = \context_course::instance($othercourse->id);
-
 
1242
 
-
 
1243
        foreach ($questions as $question) {
-
 
1244
            $question->contextid = $qcat->contextid;
-
 
1245
        }
-
 
1246
 
-
 
1247
        // Create tags in the course category context.
-
 
1248
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1249
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1250
        // Create tags in the course context.
-
 
1251
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
-
 
1252
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
-
 
1253
        // Create tags in the other course context. These should be deleted.
-
 
1254
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $othercoursecontext, ['delete']);
-
 
1255
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $othercoursecontext, ['delete']);
-
 
1256
 
-
 
1257
        // Move the questions to the activity context which is a child context of
-
 
1258
        // $coursecontext.
-
 
1259
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1260
 
-
 
1261
        foreach ($questions as $question) {
-
 
1262
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1263
            // Each question should have 2 tags.
-
 
1264
            $this->assertCount(2, $tags);
-
 
1265
 
-
 
1266
            foreach ($tags as $tag) {
-
 
1267
                // Make sure we don't have any 'delete' tags.
-
 
1268
                $this->assertContains($tag->name, ['foo', 'ctag']);
-
 
1269
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1270
            }
-
 
1271
        }
-
 
1272
    }
-
 
1273
 
-
 
1274
    /**
-
 
1275
     * When moving from a course context down into an activity context all of the
-
 
1276
     * course tags should move into the activity context.
625
     * When moving all tags from one activity context into another activity context.
1277
     */
-
 
1278
    public function test_question_move_question_tags_to_new_context_course_to_activity_qtags(): void {
-
 
1279
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
-
 
1280
        $question1 = $questions[0];
-
 
1281
        $question2 = $questions[1];
-
 
1282
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1283
        $newcontext = \context_module::instance($quiz->cmid);
-
 
1284
 
-
 
1285
        foreach ($questions as $question) {
-
 
1286
            $question->contextid = $qcat->contextid;
-
 
1287
        }
-
 
1288
 
-
 
1289
        // Create tags in the course context.
-
 
1290
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1291
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1292
 
626
     *
1293
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1294
 
-
 
1295
        foreach ($questions as $question) {
-
 
1296
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1297
 
-
 
1298
            foreach ($tags as $tag) {
-
 
1299
                $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1300
            }
-
 
1301
        }
-
 
1302
    }
-
 
1303
 
-
 
1304
    /**
-
 
1305
     * When moving from a course context down into an activity context all of the
-
 
1306
     * course tags should move into the activity context.
627
     * @covers ::question_move_question_tags_to_new_context()
1307
     */
628
     */
1308
    public function test_question_move_question_tags_to_new_context_activity_to_course_qtags(): void {
629
    public function test_question_move_question_tags_to_new_context_activity_to_activity_qtags(): void {
-
 
630
        [$category, $course, $quiz, $qcat, $questions] = $this->setup_quiz_and_questions();
1309
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions();
631
        $qbank = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
1310
        $question1 = $questions[0];
632
        $question1 = $questions[0];
1311
        $question2 = $questions[1];
633
        $question2 = $questions[1];
1312
        $qcontext = \context::instance_by_id($qcat->contextid);
634
        $qcontext = \context::instance_by_id($qcat->contextid);
Línea 1313... Línea 635...
1313
        $newcontext = \context_course::instance($course->id);
635
        $newcontext = \context_module::instance($qbank->cmid);
1314
 
636
 
1315
        foreach ($questions as $question) {
637
        foreach ($questions as $question) {
Línea 1316... Línea 638...
1316
            $question->contextid = $qcat->contextid;
638
            $question->contextid = $qcat->contextid;
1317
        }
639
        }
1318
 
640
 
Línea 1319... Línea 641...
1319
        // Create tags in the activity context.
641
        // Create tags in the quiz context.
Línea 1330... Línea 652...
1330
            }
652
            }
1331
        }
653
        }
1332
    }
654
    }
Línea 1333... Línea 655...
1333
 
655
 
1334
    /**
-
 
1335
     * question_move_question_tags_to_new_context should update all of the
-
 
1336
     * question tags contexts when they are moving down (from system to course
-
 
1337
     * category context).
-
 
1338
     *
-
 
1339
     * Course tags within the new category context should remain while any course
-
 
1340
     * tags in course contexts that can no longer access the question should be
-
 
1341
     * deleted.
-
 
1342
     */
-
 
1343
    public function test_question_move_question_tags_to_new_context_system_to_course_cat_with_orphaned_tags(): void {
-
 
1344
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
-
 
1345
        $question1 = $questions[0];
-
 
1346
        $question2 = $questions[1];
-
 
1347
        $othercategory = $this->getDataGenerator()->create_category();
-
 
1348
        $othercourse = $this->getDataGenerator()->create_course(['category' => $othercategory->id]);
-
 
1349
        $qcontext = \context::instance_by_id($qcat->contextid);
-
 
1350
        $newcontext = \context_coursecat::instance($category->id);
-
 
1351
        $othercategorycontext = \context_coursecat::instance($othercategory->id);
-
 
1352
        $coursecontext = \context_course::instance($course->id);
-
 
1353
        $othercoursecontext = \context_course::instance($othercourse->id);
-
 
1354
 
-
 
1355
        foreach ($questions as $question) {
-
 
1356
            $question->contextid = $qcat->contextid;
-
 
1357
        }
-
 
1358
 
-
 
1359
        // Create tags in the system context.
-
 
1360
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
-
 
1361
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
-
 
1362
        // Create tags in the child course context of the new context.
-
 
1363
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['bar']);
-
 
1364
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['bar']);
-
 
1365
        // Create tags in the other course context. These should be deleted when
-
 
1366
        // the question moves to the new course category context because this
-
 
1367
        // course belongs to a different category, which means it will no longer
-
 
1368
        // have access to the question.
-
 
1369
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $othercoursecontext, ['delete']);
-
 
1370
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $othercoursecontext, ['delete']);
-
 
1371
 
-
 
1372
        question_move_question_tags_to_new_context($questions, $newcontext);
-
 
1373
 
-
 
1374
        foreach ($questions as $question) {
-
 
1375
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1376
            // Each question should have two tags, 'foo' and 'bar'.
-
 
1377
            $this->assertCount(2, $tags);
-
 
1378
 
-
 
1379
            // All of the tags should have their context id set to the new context
-
 
1380
            // (course category context).
-
 
1381
            foreach ($tags as $tag) {
-
 
1382
                $this->assertContains($tag->name, ['foo', 'bar']);
-
 
1383
 
-
 
1384
                if ($tag->name == 'foo') {
-
 
1385
                    $this->assertEquals($newcontext->id, $tag->taginstancecontextid);
-
 
1386
                } else {
-
 
1387
                    $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
1388
                }
-
 
1389
            }
-
 
1390
        }
-
 
1391
    }
-
 
1392
 
-
 
1393
    /**
656
    /**
1394
     * question_sort_tags() includes the tags for all questions in the list.
657
     * question_sort_tags() includes the tags for all questions in the list.
1395
     */
658
     */
Línea 1396... Línea 659...
1396
    public function test_question_sort_tags_includes_question_tags(): void {
659
    public function test_question_sort_tags_includes_question_tags(): void {
1397
 
660
 
1398
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
661
        [$category, $course, $quiz, $qcat, $questions] = $this->setup_quiz_and_questions();
1399
        $question1 = $questions[0];
662
        $question1 = $questions[0];
Línea 1400... Línea 663...
1400
        $question2 = $questions[1];
663
        $question2 = $questions[1];
Línea 1421... Línea 684...
1421
            sort($tags);
684
            sort($tags);
1422
            sort($actualtagobjects);
685
            sort($actualtagobjects);
Línea 1423... Línea 686...
1423
 
686
 
1424
            // The question should have a full set of each tag object.
687
            // The question should have a full set of each tag object.
1425
            $this->assertEquals($tags, $actualtagobjects);
-
 
1426
            // The question should not have any course tags.
-
 
1427
            $this->assertEmpty($tagobjects->coursetagobjects);
-
 
1428
        }
-
 
1429
    }
-
 
1430
 
-
 
1431
    /**
-
 
1432
     * question_sort_tags() includes course tags for all questions in the list.
-
 
1433
     */
-
 
1434
    public function test_question_sort_tags_includes_question_course_tags(): void {
-
 
1435
        global $DB;
-
 
1436
 
-
 
1437
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1438
        $question1 = $questions[0];
-
 
1439
        $question2 = $questions[1];
-
 
1440
        $coursecontext = \context_course::instance($course->id);
-
 
1441
 
-
 
1442
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo', 'bar']);
-
 
1443
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['baz', 'bop']);
-
 
1444
 
-
 
1445
        foreach ($questions as $question) {
-
 
1446
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1447
            $tagobjects = question_sort_tags($tags, $qcat);
-
 
1448
 
-
 
1449
            $expectedtags = [];
-
 
1450
            $actualtags = $tagobjects->coursetags;
-
 
1451
            foreach ($actualtags as $coursetagid => $coursetagname) {
-
 
1452
                $expectedtags[$coursetagid] = $coursetagname;
-
 
1453
            }
-
 
1454
 
-
 
1455
            // The question should have a tags property populated with each tag id
-
 
1456
            // and display name as a key vale pair.
-
 
1457
            $this->assertEquals($expectedtags, $actualtags);
-
 
1458
 
-
 
1459
            $actualtagobjects = $tagobjects->coursetagobjects;
-
 
1460
            sort($tags);
-
 
1461
            sort($actualtagobjects);
-
 
1462
 
-
 
1463
            // The question should have a full set of each tag object.
-
 
1464
            $this->assertEquals($tags, $actualtagobjects);
-
 
1465
            // The question should not have any course tags.
-
 
1466
            $this->assertEmpty($tagobjects->tagobjects);
-
 
1467
        }
-
 
1468
    }
-
 
1469
 
-
 
1470
    /**
-
 
1471
     * question_sort_tags() should return tags from all course contexts by default.
-
 
1472
     */
-
 
1473
    public function test_question_sort_tags_includes_multiple_courses_tags(): void {
-
 
1474
        global $DB;
-
 
1475
 
-
 
1476
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1477
        $question1 = $questions[0];
-
 
1478
        $question2 = $questions[1];
-
 
1479
        $coursecontext = \context_course::instance($course->id);
-
 
1480
        // Create a sibling course.
-
 
1481
        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
-
 
1482
        $siblingcoursecontext = \context_course::instance($siblingcourse->id);
-
 
1483
 
-
 
1484
        // Create course tags.
-
 
1485
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['c1']);
-
 
1486
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['c1']);
-
 
1487
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['c2']);
-
 
1488
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['c2']);
-
 
1489
 
-
 
1490
        foreach ($questions as $question) {
-
 
1491
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1492
            $tagobjects = question_sort_tags($tags, $qcat);
-
 
1493
            $this->assertCount(2, $tagobjects->coursetagobjects);
-
 
1494
 
-
 
1495
            foreach ($tagobjects->coursetagobjects as $tag) {
-
 
1496
                if ($tag->name == 'c1') {
-
 
1497
                    $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
1498
                } else {
-
 
1499
                    $this->assertEquals($siblingcoursecontext->id, $tag->taginstancecontextid);
-
 
1500
                }
-
 
1501
            }
-
 
1502
        }
-
 
1503
    }
-
 
1504
 
-
 
1505
    /**
-
 
1506
     * question_sort_tags() should filter the course tags by the given list of courses.
-
 
1507
     */
-
 
1508
    public function test_question_sort_tags_includes_filter_course_tags(): void {
-
 
1509
        global $DB;
-
 
1510
 
-
 
1511
        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
-
 
1512
        $question1 = $questions[0];
-
 
1513
        $question2 = $questions[1];
-
 
1514
        $coursecontext = \context_course::instance($course->id);
-
 
1515
        // Create a sibling course.
-
 
1516
        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
-
 
1517
        $siblingcoursecontext = \context_course::instance($siblingcourse->id);
-
 
1518
 
-
 
1519
        // Create course tags.
-
 
1520
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo']);
-
 
1521
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['bar']);
-
 
1522
        // Create sibling course tags. These should be filtered out.
-
 
1523
        \core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['filtered1']);
-
 
1524
        \core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['filtered2']);
-
 
1525
 
-
 
1526
        foreach ($questions as $question) {
-
 
1527
            $tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
-
 
1528
            $tagobjects = question_sort_tags($tags, $qcat, [$course]);
-
 
1529
            foreach ($tagobjects->coursetagobjects as $tag) {
-
 
1530
 
-
 
1531
                // We should only be seeing course tags from $course. The tags from
-
 
1532
                // $siblingcourse should have been filtered out.
-
 
1533
                $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
-
 
1534
            }
688
            $this->assertEquals($tags, $actualtagobjects);
1535
        }
689
        }
Línea 1536... Línea 690...
1536
    }
690
    }
1537
 
691
 
1538
    /**
692
    /**
1539
     * Data provider for tests of question_has_capability_on_context and question_require_capability_on_context.
693
     * Data provider for tests of question_has_capability_on_context and question_require_capability_on_context.
1540
     *
694
     *
1541
     * @return  array
695
     * @return  array
1542
     */
696
     */
1543
    public function question_capability_on_question_provider() {
697
    public static function question_capability_on_question_provider(): array {
1544
        return [
698
        return [
1545
            'Unrelated capability which is present' => [
699
            'Unrelated capability which is present' => [
1546
                'capabilities' => [
700
                'capabilities' => [
1547
                    'moodle/question:config' => CAP_ALLOW,
701
                    'moodle/question:config' => CAP_ALLOW,
1548
                ],
702
                ],
1549
                'testcapability' => 'config',
703
                'capability' => 'config',
1550
                'isowner' => true,
704
                'isowner' => true,
1551
                'expect' => true,
705
                'expect' => true,
1552
            ],
706
            ],
1553
            'Unrelated capability which is present (not owner)' => [
707
            'Unrelated capability which is present (not owner)' => [
1554
                'capabilities' => [
708
                'capabilities' => [
1555
                    'moodle/question:config' => CAP_ALLOW,
709
                    'moodle/question:config' => CAP_ALLOW,
1556
                ],
710
                ],
1557
                'testcapability' => 'config',
711
                'capability' => 'config',
1558
                'isowner' => false,
712
                'isowner' => false,
1559
                'expect' => true,
713
                'expect' => true,
1560
            ],
714
            ],
1561
            'Unrelated capability which is not set' => [
715
            'Unrelated capability which is not set' => [
1562
                'capabilities' => [
716
                'capabilities' => [
1563
                ],
717
                ],
1564
                'testcapability' => 'config',
718
                'capability' => 'config',
1565
                'isowner' => true,
719
                'isowner' => true,
1566
                'expect' => false,
720
                'expect' => false,
1567
            ],
721
            ],
1568
            'Unrelated capability which is not set (not owner)' => [
722
            'Unrelated capability which is not set (not owner)' => [
1569
                'capabilities' => [
723
                'capabilities' => [
1570
                ],
724
                ],
1571
                'testcapability' => 'config',
725
                'capability' => 'config',
1572
                'isowner' => false,
726
                'isowner' => false,
1573
                'expect' => false,
727
                'expect' => false,
1574
            ],
728
            ],
1575
            'Unrelated capability which is prevented' => [
729
            'Unrelated capability which is prevented' => [
1576
                'capabilities' => [
730
                'capabilities' => [
1577
                    'moodle/question:config' => CAP_PREVENT,
731
                    'moodle/question:config' => CAP_PREVENT,
1578
                ],
732
                ],
1579
                'testcapability' => 'config',
733
                'capability' => 'config',
1580
                'isowner' => true,
734
                'isowner' => true,
1581
                'expect' => false,
735
                'expect' => false,
1582
            ],
736
            ],
1583
            'Unrelated capability which is prevented (not owner)' => [
737
            'Unrelated capability which is prevented (not owner)' => [
1584
                'capabilities' => [
738
                'capabilities' => [
1585
                    'moodle/question:config' => CAP_PREVENT,
739
                    'moodle/question:config' => CAP_PREVENT,
1586
                ],
740
                ],
1587
                'testcapability' => 'config',
741
                'capability' => 'config',
1588
                'isowner' => false,
742
                'isowner' => false,
1589
                'expect' => false,
743
                'expect' => false,
1590
            ],
744
            ],
1591
            'Related capability which is not set' => [
745
            'Related capability which is not set' => [
1592
                'capabilities' => [
746
                'capabilities' => [
1593
                ],
747
                ],
1594
                'testcapability' => 'edit',
748
                'capability' => 'edit',
1595
                'isowner' => true,
749
                'isowner' => true,
1596
                'expect' => false,
750
                'expect' => false,
1597
            ],
751
            ],
1598
            'Related capability which is not set (not owner)' => [
752
            'Related capability which is not set (not owner)' => [
1599
                'capabilities' => [
753
                'capabilities' => [
1600
                ],
754
                ],
1601
                'testcapability' => 'edit',
755
                'capability' => 'edit',
1602
                'isowner' => false,
756
                'isowner' => false,
1603
                'expect' => false,
757
                'expect' => false,
1604
            ],
758
            ],
1605
            'Related capability which is allowed at all, unset at mine' => [
759
            'Related capability which is allowed at all, unset at mine' => [
1606
                'capabilities' => [
760
                'capabilities' => [
1607
                    'moodle/question:editall' => CAP_ALLOW,
761
                    'moodle/question:editall' => CAP_ALLOW,
1608
                ],
762
                ],
1609
                'testcapability' => 'edit',
763
                'capability' => 'edit',
1610
                'isowner' => true,
764
                'isowner' => true,
1611
                'expect' => true,
765
                'expect' => true,
1612
            ],
766
            ],
1613
            'Related capability which is allowed at all, unset at mine (not owner)' => [
767
            'Related capability which is allowed at all, unset at mine (not owner)' => [
1614
                'capabilities' => [
768
                'capabilities' => [
1615
                    'moodle/question:editall' => CAP_ALLOW,
769
                    'moodle/question:editall' => CAP_ALLOW,
1616
                ],
770
                ],
1617
                'testcapability' => 'edit',
771
                'capability' => 'edit',
1618
                'isowner' => false,
772
                'isowner' => false,
1619
                'expect' => true,
773
                'expect' => true,
1620
            ],
774
            ],
1621
            'Related capability which is allowed at all, prevented at mine' => [
775
            'Related capability which is allowed at all, prevented at mine' => [
1622
                'capabilities' => [
776
                'capabilities' => [
1623
                    'moodle/question:editall' => CAP_ALLOW,
777
                    'moodle/question:editall' => CAP_ALLOW,
1624
                    'moodle/question:editmine' => CAP_PREVENT,
778
                    'moodle/question:editmine' => CAP_PREVENT,
1625
                ],
779
                ],
1626
                'testcapability' => 'edit',
780
                'capability' => 'edit',
1627
                'isowner' => true,
781
                'isowner' => true,
1628
                'expect' => true,
782
                'expect' => true,
1629
            ],
783
            ],
1630
            'Related capability which is allowed at all, prevented at mine (not owner)' => [
784
            'Related capability which is allowed at all, prevented at mine (not owner)' => [
1631
                'capabilities' => [
785
                'capabilities' => [
1632
                    'moodle/question:editall' => CAP_ALLOW,
786
                    'moodle/question:editall' => CAP_ALLOW,
1633
                    'moodle/question:editmine' => CAP_PREVENT,
787
                    'moodle/question:editmine' => CAP_PREVENT,
1634
                ],
788
                ],
1635
                'testcapability' => 'edit',
789
                'capability' => 'edit',
1636
                'isowner' => false,
790
                'isowner' => false,
1637
                'expect' => true,
791
                'expect' => true,
1638
            ],
792
            ],
1639
            'Related capability which is unset all, allowed at mine' => [
793
            'Related capability which is unset all, allowed at mine' => [
1640
                'capabilities' => [
794
                'capabilities' => [
1641
                    'moodle/question:editall' => CAP_PREVENT,
795
                    'moodle/question:editall' => CAP_PREVENT,
1642
                    'moodle/question:editmine' => CAP_ALLOW,
796
                    'moodle/question:editmine' => CAP_ALLOW,
1643
                ],
797
                ],
1644
                'testcapability' => 'edit',
798
                'capability' => 'edit',
1645
                'isowner' => true,
799
                'isowner' => true,
1646
                'expect' => true,
800
                'expect' => true,
1647
            ],
801
            ],
1648
            'Related capability which is unset all, allowed at mine (not owner)' => [
802
            'Related capability which is unset all, allowed at mine (not owner)' => [
1649
                'capabilities' => [
803
                'capabilities' => [
1650
                    'moodle/question:editall' => CAP_PREVENT,
804
                    'moodle/question:editall' => CAP_PREVENT,
1651
                    'moodle/question:editmine' => CAP_ALLOW,
805
                    'moodle/question:editmine' => CAP_ALLOW,
1652
                ],
806
                ],
1653
                'testcapability' => 'edit',
807
                'capability' => 'edit',
1654
                'isowner' => false,
808
                'isowner' => false,
1655
                'expect' => false,
809
                'expect' => false,
1656
            ],
810
            ],
Línea 1666... Línea 820...
1666
        // Create the test data.
820
        // Create the test data.
1667
        $generator = $this->getDataGenerator();
821
        $generator = $this->getDataGenerator();
1668
         /** @var \core_question_generator $questiongenerator */
822
         /** @var \core_question_generator $questiongenerator */
1669
         $questiongenerator = $generator->get_plugin_generator('core_question');
823
         $questiongenerator = $generator->get_plugin_generator('core_question');
Línea 1670... Línea -...
1670
 
-
 
1671
        $category = $generator->create_category();
824
 
1672
        $context = \context_coursecat::instance($category->id);
825
        $context = $this->create_course_and_question_bank();
1673
        $questioncat = $questiongenerator->create_question_category([
826
        $questioncat = $questiongenerator->create_question_category([
1674
            'contextid' => $context->id,
827
            'contextid' => $context->id,
Línea 1675... Línea 828...
1675
        ]);
828
        ]);
1676
 
829
 
1677
        // Create a cloze question.
830
        // Create a cloze question.
1678
        $question = $questiongenerator->create_question('multianswer', null, [
831
        $question = $questiongenerator->create_question('ddwtos', null, [
1679
            'category' => $questioncat->id,
832
            'category' => $questioncat->id,
1680
        ]);
833
        ]);
Línea 1681... Línea 834...
1681
        // Now, break the question.
834
        // Now, break the question.
Línea 1682... Línea 835...
1682
        $DB->delete_records('question_multianswer', ['question' => $question->id]);
835
        $DB->delete_records('question_ddwtos', ['questionid' => $question->id]);
1683
 
836
 
Línea 1750... Línea 903...
1750
        /** @var \core_question_generator $questiongenerator */
903
        /** @var \core_question_generator $questiongenerator */
1751
        $questiongenerator = $generator->get_plugin_generator('core_question');
904
        $questiongenerator = $generator->get_plugin_generator('core_question');
1752
        $user = $generator->create_user();
905
        $user = $generator->create_user();
1753
        $otheruser = $generator->create_user();
906
        $otheruser = $generator->create_user();
1754
        $roleid = $generator->create_role();
907
        $roleid = $generator->create_role();
1755
        $category = $generator->create_category();
-
 
1756
        $context = \context_coursecat::instance($category->id);
908
        $context = $this->create_course_and_question_bank();
1757
        $questioncat = $questiongenerator->create_question_category([
909
        $questioncat = $questiongenerator->create_question_category([
1758
            'contextid' => $context->id,
910
            'contextid' => $context->id,
1759
        ]);
911
        ]);
Línea 1760... Línea 912...
1760
 
912
 
Línea 1797... Línea 949...
1797
        /** @var \core_question_generator $questiongenerator */
949
        /** @var \core_question_generator $questiongenerator */
1798
        $questiongenerator = $generator->get_plugin_generator('core_question');
950
        $questiongenerator = $generator->get_plugin_generator('core_question');
1799
        $user = $generator->create_user();
951
        $user = $generator->create_user();
1800
        $otheruser = $generator->create_user();
952
        $otheruser = $generator->create_user();
1801
        $roleid = $generator->create_role();
953
        $roleid = $generator->create_role();
1802
        $category = $generator->create_category();
-
 
1803
        $context = \context_coursecat::instance($category->id);
954
        $context = $this->create_course_and_question_bank();
1804
        $questioncat = $questiongenerator->create_question_category([
955
        $questioncat = $questiongenerator->create_question_category([
1805
            'contextid' => $context->id,
956
            'contextid' => $context->id,
1806
        ]);
957
        ]);
Línea 1807... Línea 958...
1807
 
958
 
Línea 1844... Línea 995...
1844
        /** @var \core_question_generator $questiongenerator */
995
        /** @var \core_question_generator $questiongenerator */
1845
        $questiongenerator = $generator->get_plugin_generator('core_question');
996
        $questiongenerator = $generator->get_plugin_generator('core_question');
1846
        $user = $generator->create_user();
997
        $user = $generator->create_user();
1847
        $otheruser = $generator->create_user();
998
        $otheruser = $generator->create_user();
1848
        $roleid = $generator->create_role();
999
        $roleid = $generator->create_role();
1849
        $category = $generator->create_category();
-
 
1850
        $context = \context_coursecat::instance($category->id);
1000
        $context = $this->create_course_and_question_bank();
1851
        $questioncat = $questiongenerator->create_question_category([
1001
        $questioncat = $questiongenerator->create_question_category([
1852
            'contextid' => $context->id,
1002
            'contextid' => $context->id,
1853
        ]);
1003
        ]);
Línea 1854... Línea 1004...
1854
 
1004
 
Línea 1891... Línea 1041...
1891
        /** @var \core_question_generator $questiongenerator */
1041
        /** @var \core_question_generator $questiongenerator */
1892
        $questiongenerator = $generator->get_plugin_generator('core_question');
1042
        $questiongenerator = $generator->get_plugin_generator('core_question');
1893
        $user = $generator->create_user();
1043
        $user = $generator->create_user();
1894
        $otheruser = $generator->create_user();
1044
        $otheruser = $generator->create_user();
1895
        $roleid = $generator->create_role();
1045
        $roleid = $generator->create_role();
1896
        $category = $generator->create_category();
1046
        $context = $this->create_course_and_question_bank();
1897
        $context = \context_coursecat::instance($category->id);
1047
        $coursecontext = $context->get_course_context();
1898
        $questioncat = $questiongenerator->create_question_category([
1048
        $questioncat = $questiongenerator->create_question_category([
1899
            'contextid' => $context->id,
1049
            'contextid' => $context->id,
1900
        ]);
1050
        ]);
Línea 1901... Línea 1051...
1901
 
1051
 
1902
        $newcategory = $generator->create_category();
1052
        $qbank2 = $generator->create_module('qbank', ['course' => $coursecontext->instanceid]);
1903
        $newcontext = \context_coursecat::instance($newcategory->id);
1053
        $newcontext = \context_module::instance($qbank2->cmid);
1904
        $newquestioncat = $questiongenerator->create_question_category([
1054
        $newquestioncat = $questiongenerator->create_question_category([
1905
            'contextid' => $newcontext->id,
1055
            'contextid' => $newcontext->id,
Línea 1906... Línea 1056...
1906
        ]);
1056
        ]);
Línea 1948... Línea 1098...
1948
        /** @var \core_question_generator $questiongenerator */
1098
        /** @var \core_question_generator $questiongenerator */
1949
        $questiongenerator = $generator->get_plugin_generator('core_question');
1099
        $questiongenerator = $generator->get_plugin_generator('core_question');
1950
        $user = $generator->create_user();
1100
        $user = $generator->create_user();
1951
        $otheruser = $generator->create_user();
1101
        $otheruser = $generator->create_user();
1952
        $roleid = $generator->create_role();
1102
        $roleid = $generator->create_role();
1953
        $category = $generator->create_category();
-
 
1954
        $context = \context_coursecat::instance($category->id);
1103
        $context = $this->create_course_and_question_bank();
1955
        $questioncat = $questiongenerator->create_question_category([
1104
        $questioncat = $questiongenerator->create_question_category([
1956
            'contextid' => $context->id,
1105
            'contextid' => $context->id,
1957
        ]);
1106
        ]);
Línea 1958... Línea 1107...
1958
 
1107
 
Línea 1984... Línea 1133...
1984
        $generator = $this->getDataGenerator();
1133
        $generator = $this->getDataGenerator();
1985
        /** @var \core_question_generator $questiongenerator */
1134
        /** @var \core_question_generator $questiongenerator */
1986
        $questiongenerator = $generator->get_plugin_generator('core_question');
1135
        $questiongenerator = $generator->get_plugin_generator('core_question');
1987
        $user = $generator->create_user();
1136
        $user = $generator->create_user();
Línea 1988... Línea -...
1988
 
-
 
1989
        $category = $generator->create_category();
1137
 
1990
        $context = \context_coursecat::instance($category->id);
1138
        $context = $this->create_course_and_question_bank();
1991
        $questioncat = $questiongenerator->create_question_category([
1139
        $questioncat = $questiongenerator->create_question_category([
1992
            'contextid' => $context->id,
1140
            'contextid' => $context->id,
Línea 1993... Línea 1141...
1993
        ]);
1141
        ]);
Línea 2062... Línea 1210...
2062
 
1210
 
2063
        // Create a category tree.
1211
        // Create a category tree.
2064
        /** @var \core_question_generator $questiongenerator */
1212
        /** @var \core_question_generator $questiongenerator */
2065
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
1213
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
2066
        // Create a Course.
1214
        // Create a Course.
2067
        $course = $this->getDataGenerator()->create_course();
-
 
Línea 2068... Línea 1215...
2068
        $coursecontext = \context_course::instance($course->id);
1215
        $context = $this->create_course_and_question_bank();
2069
 
1216
 
2070
        $top = question_get_top_category($coursecontext->id, true);
1217
        $top = question_get_top_category($context->id, true);
2071
        $cat1 = $questiongenerator->create_question_category(['parent' => $top->id]);
1218
        $cat1 = question_get_default_category($context->id);
2072
        $sub11 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
1219
        $sub11 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
2073
        $sub12 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
1220
        $sub12 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
Línea 2096... Línea 1243...
2096
    public function test_question_categorylist_bad_data(): void {
1243
    public function test_question_categorylist_bad_data(): void {
2097
        $this->resetAfterTest();
1244
        $this->resetAfterTest();
Línea 2098... Línea 1245...
2098
 
1245
 
2099
        // Create a category tree.
1246
        // Create a category tree.
-
 
1247
        $course = $this->getDataGenerator()->create_course();
2100
        $course = $this->getDataGenerator()->create_course();
1248
        $qbank1 = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
-
 
1249
        $bank1context = \context_module::instance($qbank1->cmid);
2101
        $coursecontext = \context_course::instance($course->id);
1250
        $qbank2 = self::getDataGenerator()->create_module('qbank', ['course' => $course->id]);
2102
        /** @var \core_question_generator $questiongenerator */
1251
        /** @var \core_question_generator $questiongenerator */
2103
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
1252
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
Línea 2104... Línea 1253...
2104
        $context = \context_system::instance();
1253
        $wrongcontext = \context_module::instance($qbank2->cmid);
2105
 
1254
 
2106
        $top = question_get_top_category($coursecontext->id, true);
1255
        $top = question_get_top_category($bank1context->id, true);
2107
        $cat1 = $questiongenerator->create_question_category(['parent' => $top->id]);
1256
        $cat1 = question_get_default_category($bank1context->id);
2108
        $sub11 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
1257
        $sub11 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
2109
        $sub12 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
1258
        $sub12 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
Línea 2110... Línea 1259...
2110
        $cat2 = $questiongenerator->create_question_category(['parent' => $top->id, 'contextid' => $context->id]);
1259
        $cat2 = $questiongenerator->create_question_category(['parent' => $top->id, 'contextid' => $wrongcontext->id]);
2111
        $sub22 = $questiongenerator->create_question_category(['parent' => $cat2->id]);
1260
        $sub22 = $questiongenerator->create_question_category(['parent' => $cat2->id]);
2112
 
1261
 
Línea 2124... Línea 1273...
2124
    public function test_question_categorylist_parents(): void {
1273
    public function test_question_categorylist_parents(): void {
2125
        $this->resetAfterTest();
1274
        $this->resetAfterTest();
2126
        $generator = $this->getDataGenerator();
1275
        $generator = $this->getDataGenerator();
2127
        /** @var \core_question_generator $questiongenerator */
1276
        /** @var \core_question_generator $questiongenerator */
2128
        $questiongenerator = $generator->get_plugin_generator('core_question');
1277
        $questiongenerator = $generator->get_plugin_generator('core_question');
2129
        $category = $generator->create_category();
-
 
2130
        $context = \context_coursecat::instance($category->id);
1278
        $context = $this->create_course_and_question_bank();
2131
        // Create a top category.
1279
        // Create a top category.
2132
        $cat0 = question_get_top_category($context->id, true);
1280
        $cat0 = question_get_top_category($context->id, true);
2133
        // Add sub-categories.
1281
        // Add sub-categories.
2134
        $cat1 = $questiongenerator->create_question_category(['parent' => $cat0->id]);
1282
        $cat1 = $questiongenerator->create_question_category(['parent' => $cat0->id]);
2135
        $cat2 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
1283
        $cat2 = $questiongenerator->create_question_category(['parent' => $cat1->id]);
Línea 2149... Línea 1297...
2149
    public function test_question_categorylist_parents_bad_data(): void {
1297
    public function test_question_categorylist_parents_bad_data(): void {
2150
        $this->resetAfterTest();
1298
        $this->resetAfterTest();
2151
        $generator = $this->getDataGenerator();
1299
        $generator = $this->getDataGenerator();
2152
        /** @var \core_question_generator $questiongenerator */
1300
        /** @var \core_question_generator $questiongenerator */
2153
        $questiongenerator = $generator->get_plugin_generator('core_question');
1301
        $questiongenerator = $generator->get_plugin_generator('core_question');
-
 
1302
        $bank1context = $this->create_course_and_question_bank();
2154
        $category = $generator->create_category();
1303
        $coursecontext = $bank1context->get_course_context();
-
 
1304
        $qbank2 = self::getDataGenerator()->create_module('qbank', ['course' => $coursecontext->instanceid]);
2155
        $context = \context_coursecat::instance($category->id);
1305
        $bank2context = \context_module::instance($qbank2->cmid);
-
 
1306
 
2156
        // Create a top category.
1307
        // Create a top category.
2157
        $cat0 = question_get_top_category($context->id, true);
1308
        $cat0 = question_get_top_category($bank1context->id, true);
2158
        // Add sub-categories - but in a different context.
1309
        // Add sub-categories - but in a different context.
2159
        $cat1 = $questiongenerator->create_question_category(
1310
        $cat1 = $questiongenerator->create_question_category(
2160
            ['parent' => $cat0->id, 'contextid' => \context_system::instance()->id]);
1311
            ['parent' => $cat0->id, 'contextid' => $bank2context->id]);
2161
        $cat2 = $questiongenerator->create_question_category(
1312
        $cat2 = $questiongenerator->create_question_category(
2162
            ['parent' => $cat1->id, 'contextid' => \context_system::instance()->id]);
1313
            ['parent' => $cat1->id, 'contextid' => $bank2context->id]);
Línea 2163... Línea 1314...
2163
 
1314
 
2164
        // Test the 'get parents' function only returns categories in the same context.
1315
        // Test the 'get parents' function only returns categories in the same context.
2165
        $this->assertEquals([$cat1->id], question_categorylist_parents($cat2->id));
1316
        $this->assertEquals([$cat1->id], question_categorylist_parents($cat2->id));
Línea 2166... Línea 1317...
2166
    }
1317
    }
2167
 
1318
 
2168
    /**
1319
    /**
2169
     * Get test cases for test_core_question_find_next_unused_idnumber.
1320
     * Get test cases for test_core_question_find_next_unused_idnumber.
2170
     *
1321
     *
2171
     * @return array test cases.
1322
     * @return array test cases.
2172
     */
1323
     */
2173
    public function find_next_unused_idnumber_cases(): array {
1324
    public static function find_next_unused_idnumber_cases(): array {
2174
        return [
1325
        return [
2175
            [null, null],
1326
            [null, null],
2176
            ['id', null],
1327
            ['id', null],
Línea 2313... Línea 1464...
2313
     */
1464
     */
2314
    public function test_delete_question_bank_entry(): void {
1465
    public function test_delete_question_bank_entry(): void {
2315
        global $DB;
1466
        global $DB;
2316
        $this->resetAfterTest();
1467
        $this->resetAfterTest();
2317
        // Setup.
1468
        // Setup.
2318
        $context = \context_system::instance();
1469
        $context = $this->create_course_and_question_bank();
2319
        /** @var \core_question_generator $qgen */
1470
        /** @var \core_question_generator $qgen */
2320
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
1471
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
2321
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
1472
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
2322
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
1473
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
2323
        // Make sure there is an entry in the entry table.
1474
        // Make sure there is an entry in the entry table.
Línea 2350... Línea 1501...
2350
     */
1501
     */
2351
    public function test_get_question_bank_entry(): void {
1502
    public function test_get_question_bank_entry(): void {
2352
        global $DB;
1503
        global $DB;
2353
        $this->resetAfterTest();
1504
        $this->resetAfterTest();
2354
        // Setup.
1505
        // Setup.
2355
        $context = \context_system::instance();
1506
        $context = $this->create_course_and_question_bank();
2356
        /** @var \core_question_generator $qgen */
1507
        /** @var \core_question_generator $qgen */
2357
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
1508
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
2358
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
1509
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
2359
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
1510
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
2360
        // Make sure there is an entry in the entry table.
1511
        // Make sure there is an entry in the entry table.
Línea 2380... Línea 1531...
2380
     */
1531
     */
2381
    public function test_get_question_version(): void {
1532
    public function test_get_question_version(): void {
2382
        global $DB;
1533
        global $DB;
2383
        $this->resetAfterTest();
1534
        $this->resetAfterTest();
2384
        // Setup.
1535
        // Setup.
2385
        $context = \context_system::instance();
1536
        $context = $this->create_course_and_question_bank();
2386
        /** @var \core_question_generator $qgen */
1537
        /** @var \core_question_generator $qgen */
2387
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
1538
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
2388
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
1539
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
2389
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
1540
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
2390
        // Make sure there is an entry in the entry table.
1541
        // Make sure there is an entry in the entry table.
Línea 2411... Línea 1562...
2411
     */
1562
     */
2412
    public function test_get_next_version(): void {
1563
    public function test_get_next_version(): void {
2413
        global $DB;
1564
        global $DB;
2414
        $this->resetAfterTest();
1565
        $this->resetAfterTest();
2415
        // Setup.
1566
        // Setup.
2416
        $context = \context_system::instance();
1567
        $context = $this->create_course_and_question_bank();
2417
        /** @var \core_question_generator $qgen */
1568
        /** @var \core_question_generator $qgen */
2418
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
1569
        $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
2419
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
1570
        $qcat = $qgen->create_question_category(array('contextid' => $context->id));
2420
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
1571
        $q1 = $qgen->create_question('shortanswer', null, array('category' => $qcat->id));
2421
        // Make sure there is an entry in the entry table.
1572
        // Make sure there is an entry in the entry table.
Línea 2434... Línea 1585...
2434
        $this->assertEquals(1, $record->version);
1585
        $this->assertEquals(1, $record->version);
2435
        $nextversion = get_next_version($record->id);
1586
        $nextversion = get_next_version($record->id);
2436
        $this->assertEquals(2, $nextversion);
1587
        $this->assertEquals(2, $nextversion);
2437
    }
1588
    }
Línea -... Línea 1589...
-
 
1589
 
-
 
1590
    /**
-
 
1591
     * Test moving a question category from one context to another
-
 
1592
     *
-
 
1593
     * @covers ::question_move_category_to_context
-
 
1594
     */
-
 
1595
    public function test_question_move_category_to_context(): void {
-
 
1596
 
-
 
1597
        global $CFG, $DB;
-
 
1598
 
-
 
1599
        $this->setAdminUser();
-
 
1600
 
-
 
1601
        // Create a course.
-
 
1602
        $course = self::getDataGenerator()->create_course();
-
 
1603
 
-
 
1604
        // Create a quiz activity to store our question in at the start.
-
 
1605
        $quiz1 = $this->getDataGenerator()->create_module('quiz', [
-
 
1606
            'course' => $course->id,
-
 
1607
        ]);
-
 
1608
 
-
 
1609
        // And then create another one to move the category to.
-
 
1610
        $quiz2 = $this->getDataGenerator()->create_module('quiz', [
-
 
1611
            'course' => $course->id,
-
 
1612
        ]);
-
 
1613
 
-
 
1614
        // Get the question generator and the context of the activities.
-
 
1615
        $generator = self::getDataGenerator()->get_plugin_generator('core_question');
-
 
1616
        $context1 = \context_module::instance($quiz1->cmid);
-
 
1617
        $context2 = \context_module::instance($quiz2->cmid);
-
 
1618
 
-
 
1619
        // Create a question category within our first quiz activity.
-
 
1620
        $category = $generator->create_question_category(['contextid' => $context1->id]);
-
 
1621
 
-
 
1622
        // And create a question within that.
-
 
1623
        // We will use `truefalse` but it could be any type.
-
 
1624
        $question = $generator->create_question('truefalse', null, ['category' => $category->id]);
-
 
1625
 
-
 
1626
        $areas = [
-
 
1627
            'questiontext' => '1.jpg',
-
 
1628
            'generalfeedback' => '2.jpg',
-
 
1629
        ];
-
 
1630
 
-
 
1631
        // Add file records to each of the file areas, for our first quiz activity.
-
 
1632
        foreach ($areas as $area => $img) {
-
 
1633
            $fs = get_file_storage();
-
 
1634
            $filerecord = new \stdClass();
-
 
1635
            $filerecord->contextid = $context1->id;
-
 
1636
            $filerecord->component = 'question';
-
 
1637
            $filerecord->filearea = $area;
-
 
1638
            $filerecord->itemid = $question->id;
-
 
1639
            $filerecord->filepath = '/';
-
 
1640
            $filerecord->filename = $img;
-
 
1641
            $fs->create_file_from_pathname($filerecord, $CFG->dirroot .
-
 
1642
                '/lib/tests/fixtures/' . $img);
-
 
1643
        }
-
 
1644
 
-
 
1645
        // Firstly, confirm that the file records exist and there were no problems creating them.
-
 
1646
        // We don't care in this test about the actual files in the data dir.
-
 
1647
        $files = $DB->get_records('files', [
-
 
1648
            'component' => 'question',
-
 
1649
            'itemid' => $question->id,
-
 
1650
            'contextid' => $context1->id,
-
 
1651
            'mimetype' => 'image/jpeg',
-
 
1652
        ]);
-
 
1653
 
-
 
1654
        $this->assertCount(2, $files);
-
 
1655
 
-
 
1656
        // Move the question category to another context.
-
 
1657
        question_move_category_to_context(
-
 
1658
            $category->id,
-
 
1659
            $context1->id,
-
 
1660
            $context2->id,
-
 
1661
        );
-
 
1662
 
-
 
1663
        // Now check that the files have been moved to the new category.
-
 
1664
        $files = $DB->get_records('files', [
-
 
1665
            'component' => 'question',
-
 
1666
            'itemid' => $question->id,
-
 
1667
            'contextid' => $context2->id,
-
 
1668
            'mimetype' => 'image/jpeg',
-
 
1669
        ]);
-
 
1670
 
-
 
1671
        $this->assertCount(2, $files);
-
 
1672
 
-
 
1673
    }
-
 
1674
 
-
 
1675
    /**
-
 
1676
     * Update the context for a set reference, keeping the original category.
-
 
1677
     *
-
 
1678
     * @covers ::move_question_set_references()
-
 
1679
     */
-
 
1680
    public function test_move_question_set_references_context(): void {
-
 
1681
        $this->setAdminUser();
-
 
1682
        // Create a course with a quiz containing a random question from a qbank context.
-
 
1683
        $randomcourse = self::getDataGenerator()->create_course(['shortname' => 'Random']);
-
 
1684
        $qbank1 = self::getDataGenerator()->get_plugin_generator('mod_qbank')->create_instance(['course' => $randomcourse->id]);
-
 
1685
        $context1 = \context_module::instance($qbank1->cmid);
-
 
1686
        $qbank2 = self::getDataGenerator()->get_plugin_generator('mod_qbank')->create_instance(['course' => $randomcourse->id]);
-
 
1687
        $context2 = \context_module::instance($qbank2->cmid);
-
 
1688
        $topcategory = question_get_top_category($context1->id, true);
-
 
1689
        $randomcategory = self::getDataGenerator()->get_plugin_generator('core_question')->create_question_category(
-
 
1690
            ['parent' => $topcategory->id],
-
 
1691
        );
-
 
1692
        $randomquiz = self::getDataGenerator()->get_plugin_generator('mod_quiz')->create_instance(
-
 
1693
            [
-
 
1694
                'course' => $randomcourse->id,
-
 
1695
                'grade' => 100.0,
-
 
1696
                'sumgrades' => 2,
-
 
1697
                'layout' => '1,0',
-
 
1698
            ],
-
 
1699
        );
-
 
1700
 
-
 
1701
        $randomquizsettings = quiz_settings::create($randomquiz->id);
-
 
1702
        $structure = $randomquizsettings->get_structure();
-
 
1703
 
-
 
1704
        $filtercondition = [
-
 
1705
            'filter' => [
-
 
1706
                'category' => [
-
 
1707
                    'jointype' => \core_question\local\bank\condition::JOINTYPE_DEFAULT,
-
 
1708
                    'values' => [$randomcategory->id],
-
 
1709
                    'filteroptions' => ['includesubcategories' => true],
-
 
1710
                ],
-
 
1711
            ],
-
 
1712
        ];
-
 
1713
        $structure->add_random_questions(1, 1, $filtercondition);
-
 
1714
        $structure = $randomquizsettings->get_structure();
-
 
1715
        $randomquestion = $structure->get_question_in_slot(1);
-
 
1716
 
-
 
1717
        $this->assertEquals($randomquestion->contextid, $context1->id);
-
 
1718
        $this->assertEquals($randomquestion->filtercondition['filter']['category']['values'][0], $randomcategory->id);
-
 
1719
 
-
 
1720
        move_question_set_references($randomcategory->id, $randomcategory->id, $context1->id, $context2->id);
-
 
1721
 
-
 
1722
        $structure = $randomquizsettings->get_structure();
-
 
1723
        $randomquestion = $structure->get_question_in_slot(1);
-
 
1724
 
-
 
1725
        $this->assertEquals($randomquestion->contextid, $context2->id);
-
 
1726
        $this->assertEquals($randomquestion->filtercondition['filter']['category']['values'][0], $randomcategory->id);
-
 
1727
    }
-
 
1728
 
-
 
1729
    /**
-
 
1730
     * Update the context and category for a set reference.
-
 
1731
     *
-
 
1732
     * @covers ::move_question_set_references()
-
 
1733
     */
-
 
1734
    public function test_move_question_set_references_category(): void {
-
 
1735
        $this->setAdminUser();
-
 
1736
        // Create a course with a quiz containing a random question from a qbank context.
-
 
1737
        $randomcourse = self::getDataGenerator()->create_course(['shortname' => 'Random']);
-
 
1738
        $qbank1 = self::getDataGenerator()->get_plugin_generator('mod_qbank')->create_instance(['course' => $randomcourse->id]);
-
 
1739
        $context1 = \context_module::instance($qbank1->cmid);
-
 
1740
        $qbank2 = self::getDataGenerator()->get_plugin_generator('mod_qbank')->create_instance(['course' => $randomcourse->id]);
-
 
1741
        $context2 = \context_module::instance($qbank2->cmid);
-
 
1742
        $topcategory1 = question_get_top_category($context1->id, true);
-
 
1743
        $topcategory2 = question_get_top_category($context2->id, true);
-
 
1744
        $randomquiz = self::getDataGenerator()->get_plugin_generator('mod_quiz')->create_instance(
-
 
1745
            [
-
 
1746
                'course' => $randomcourse->id,
-
 
1747
                'grade' => 100.0,
-
 
1748
                'sumgrades' => 2,
-
 
1749
                'layout' => '1,0',
-
 
1750
            ],
-
 
1751
        );
-
 
1752
 
-
 
1753
        $randomquizsettings = quiz_settings::create($randomquiz->id);
-
 
1754
        $structure = $randomquizsettings->get_structure();
-
 
1755
 
-
 
1756
        $filtercondition = [
-
 
1757
            'filter' => [
-
 
1758
                'category' => [
-
 
1759
                    'jointype' => \core_question\local\bank\condition::JOINTYPE_DEFAULT,
-
 
1760
                    'values' => [$topcategory1->id],
-
 
1761
                    'filteroptions' => ['includesubcategories' => true],
-
 
1762
                ],
-
 
1763
            ],
-
 
1764
        ];
-
 
1765
        $structure->add_random_questions(1, 1, $filtercondition);
-
 
1766
        $structure = $randomquizsettings->get_structure();
-
 
1767
        $randomquestion = $structure->get_question_in_slot(1);
-
 
1768
 
-
 
1769
        $this->assertEquals($randomquestion->contextid, $context1->id);
-
 
1770
        $this->assertEquals($randomquestion->filtercondition['filter']['category']['values'][0], $topcategory1->id);
-
 
1771
 
-
 
1772
        move_question_set_references($topcategory1->id, $topcategory2->id, $context1->id, $context2->id);
-
 
1773
 
-
 
1774
        $structure = $randomquizsettings->get_structure();
-
 
1775
        $randomquestion = $structure->get_question_in_slot(1);
-
 
1776
 
-
 
1777
        $this->assertEquals($randomquestion->contextid, $context2->id);
-
 
1778
        $this->assertEquals($randomquestion->filtercondition['filter']['category']['values'][0], $topcategory2->id);
2438
 
1779
    }