@@ -240,7 +240,7 @@ public function test_restore_quiz_with_same_stamp_questions(string $questionname
240
240
// Create a question category.
241
241
$ cat = $ questiongenerator ->create_question_category (['contextid ' => $ coursecontext ->id ]);
242
242
243
- // Create 2 quizzes with 2 questions multichoice .
243
+ // Create 2 quizzes with 2 questions.
244
244
$ quiz1 = $ this ->create_test_quiz ($ course1 );
245
245
$ question1 = $ questiongenerator ->create_question ('formulas ' , $ questionname , ['category ' => $ cat ->id ]);
246
246
quiz_add_quiz_question ($ question1 ->id , $ quiz1 , 0 );
@@ -288,6 +288,90 @@ public function test_restore_quiz_with_same_stamp_questions(string $questionname
288
288
$ this ->assertEquals ($ quiz2structure [2 ]->questionid , $ quiz2structure [2 ]->questionid );
289
289
}
290
290
291
+ /**
292
+ * Data provider.
293
+ *
294
+ * @return array
295
+ */
296
+ public static function provide_xml_keys_to_remove (): array {
297
+ return [
298
+ ['answernotunique ' ],
299
+ ['partindex ' ],
300
+ ];
301
+ }
302
+
303
+ /**
304
+ * Restore a quiz with a question where a field is missing in the backup.
305
+ *
306
+ * @param string $which the XML key to remove from the backup
307
+ *
308
+ * @dataProvider provide_xml_keys_to_remove
309
+ */
310
+ public function test_restore_quiz_if_field_is_missing_in_backup (string $ which ): void {
311
+ global $ CFG , $ USER ;
312
+ $ this ->resetAfterTest ();
313
+ $ this ->setAdminUser ();
314
+
315
+ // The changes introduced while fixing MDL-83541 are only present in Moodle 4.4 and newer. It
316
+ // does not make sense to perform this test with older versions.
317
+ if ($ CFG ->branch < 404 ) {
318
+ $ this ->markTestSkipped (
319
+ 'Not testing detection of duplicates while restoring in Moodle versions prior to 4.4. ' ,
320
+ );
321
+ }
322
+
323
+ // Create a course and a user with editing teacher capabilities.
324
+ $ generator = $ this ->getDataGenerator ();
325
+ $ course1 = $ generator ->create_course ();
326
+ $ teacher = $ USER ;
327
+ $ generator ->enrol_user ($ teacher ->id , $ course1 ->id , 'editingteacher ' );
328
+ $ coursecontext = \context_course::instance ($ course1 ->id );
329
+ /** @var \core_question_generator $questiongenerator */
330
+ $ questiongenerator = $ this ->getDataGenerator ()->get_plugin_generator ('core_question ' );
331
+
332
+ // Create a question category.
333
+ $ cat = $ questiongenerator ->create_question_category (['contextid ' => $ coursecontext ->id ]);
334
+
335
+ // Create a quiz with a multipart Formulas question.
336
+ $ quiz = $ this ->create_test_quiz ($ course1 );
337
+ $ question = $ questiongenerator ->create_question ('formulas ' , 'testmethodsinparts ' , ['category ' => $ cat ->id ]);
338
+ quiz_add_quiz_question ($ question ->id , $ quiz , 0 );
339
+
340
+ // Backup quiz1.
341
+ $ bc = new backup_controller (backup::TYPE_1ACTIVITY , $ quiz ->cmid , backup::FORMAT_MOODLE ,
342
+ backup::INTERACTIVE_NO , backup::MODE_IMPORT , $ teacher ->id );
343
+ $ backupid = $ bc ->get_backupid ();
344
+ $ bc ->execute_plan ();
345
+ $ bc ->destroy ();
346
+
347
+ // Delete requested entry from questions.xml file in the backup.
348
+ $ xmlfile = $ bc ->get_plan ()->get_basepath () . '/questions.xml ' ;
349
+ $ xml = file_get_contents ($ xmlfile );
350
+ $ xml = preg_replace ("=< $ which>[^<]+</ $ which>= " , '' , $ xml );
351
+ file_put_contents ($ xmlfile , $ xml );
352
+
353
+ // Restore the (modified) backup into the same course.
354
+ $ rc = new restore_controller ($ backupid , $ course1 ->id , backup::INTERACTIVE_NO , backup::MODE_IMPORT ,
355
+ $ teacher ->id , backup::TARGET_CURRENT_ADDING );
356
+ $ rc ->execute_precheck ();
357
+ $ rc ->execute_plan ();
358
+ $ rc ->destroy ();
359
+
360
+ // Verify that the newly-restored quiz uses the same question as quiz1.
361
+ $ modules = get_fast_modinfo ($ course1 ->id )->get_instances_of ('quiz ' );
362
+ $ this ->assertCount (2 , $ modules );
363
+ $ quizstructure = \mod_quiz \question \bank \qbank_helper::get_question_structure (
364
+ $ quiz ->id ,
365
+ \context_module::instance ($ quiz ->cmid ),
366
+ );
367
+ $ restoredquiz = end ($ modules );
368
+ $ restoredquizstructure = \mod_quiz \question \bank \qbank_helper::get_question_structure (
369
+ $ restoredquiz ->instance ,
370
+ $ restoredquiz ->context ,
371
+ );
372
+ $ this ->assertEquals ($ quizstructure [1 ]->questionid , $ restoredquizstructure [1 ]->questionid );
373
+ }
374
+
291
375
/**
292
376
* Restore a quiz with duplicate questions (same stamp and questions) into the same course.
293
377
* This is a contrived case, but this test serves as a control for the other tests in this class, proving
@@ -554,7 +638,7 @@ public function test_restore_quiz_with_same_stamp_questions_edited_hints(string
554
638
// Create a question category.
555
639
$ cat = $ questiongenerator ->create_question_category (['contextid ' => $ coursecontext ->id ]);
556
640
557
- // Create 2 questions multichoice .
641
+ // Create 2 questions.
558
642
$ quiz1 = $ this ->create_test_quiz ($ course1 );
559
643
$ question1 = $ questiongenerator ->create_question ('formulas ' , $ questionname , ['category ' => $ cat ->id ]);
560
644
quiz_add_quiz_question ($ question1 ->id , $ quiz1 , 0 );
@@ -669,7 +753,7 @@ public function test_restore_quiz_with_same_stamp_questions_edited_options(strin
669
753
// Create a question category.
670
754
$ cat = $ questiongenerator ->create_question_category (['contextid ' => $ coursecontext ->id ]);
671
755
672
- // A quiz with 2 multichoice questions.
756
+ // A quiz with 2 questions.
673
757
$ quiz1 = $ this ->create_test_quiz ($ course1 );
674
758
$ question1 = $ questiongenerator ->create_question ('formulas ' , 'testsinglenum ' , ['category ' => $ cat ->id ]);
675
759
quiz_add_quiz_question ($ question1 ->id , $ quiz1 , 0 );
@@ -681,7 +765,10 @@ public function test_restore_quiz_with_same_stamp_questions_edited_options(strin
681
765
$ DB ->set_field ('question ' , 'stamp ' , $ question1 ->stamp , ['id ' => $ question2 ->id ]);
682
766
683
767
// Change the options of question2 to be different to question1.
684
- $ optionfields = ['varsrandom ' , 'varsglobal ' , 'answernumbering ' , 'shownumcorrect ' , 'correctfeedback ' , 'partiallycorrectfeedback ' , 'incorrectfeedback ' ];
768
+ $ optionfields = [
769
+ 'varsrandom ' , 'varsglobal ' , 'answernumbering ' , 'shownumcorrect ' ,
770
+ 'correctfeedback ' , 'partiallycorrectfeedback ' , 'incorrectfeedback ' ,
771
+ ];
685
772
if (in_array ($ field , $ optionfields )) {
686
773
$ DB ->set_field ('qtype_formulas_options ' , $ field , $ value , ['questionid ' => $ question2 ->id ]);
687
774
} else {
0 commit comments