From cd4c824f6e1a395bc6f75d9c8fc0a860766ac760 Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Mon, 10 Nov 2025 12:02:56 +0800 Subject: [PATCH] MDL-85686 mod_quiz: unit test coverage for questions shuffle --- mod/quiz/tests/attempt_test.php | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/mod/quiz/tests/attempt_test.php b/mod/quiz/tests/attempt_test.php index f6bdc290b24..f06d8fe8a71 100644 --- a/mod/quiz/tests/attempt_test.php +++ b/mod/quiz/tests/attempt_test.php @@ -588,4 +588,56 @@ final class attempt_test extends \advanced_testcase { $questionattempt->render(new \question_display_options(), 1); $this->assertEqualsWithDelta(time(), $questionattempt->get_step(0)->get_timecreated(), 1); } + + /** + * Test that enabling shuffle on the first quiz section randomizes question order between attempts. + * + * @return void + * @covers ::quiz_start_new_attempt + */ + public function test_question_shuffle(): void { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + + // Create quiz with two sections using create_test_quiz. + $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); + $quizobj = $quizgenerator->create_test_quiz([ + 'Shuffled section*', + ['Q1', 1, 'shortanswer'], + ['Q2', 1, 'shortanswer'], + ['Q3', 1, 'shortanswer'], + ['Q4', 1, 'shortanswer'], + ['Q5', 1, 'shortanswer'], + 'Non-shuffled section', + ['Q6', 2, 'shortanswer'], + ['Q7', 2, 'shortanswer'], + ['Q8', 2, 'shortanswer'], + ['Q9', 2, 'shortanswer'], + ['Q10', 2, 'shortanswer'], + ]); + + // Start two attempts. + $attempt1 = quiz_prepare_and_start_new_attempt($quizobj, 1, null, false, [], [], $user->id); + $attempt2 = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $user->id); + $attemptobj1 = quiz_attempt::create($attempt1->id); + $attemptobj2 = quiz_attempt::create($attempt2->id); + + // Get slot numbers for each section in both attempts. + $slots1a = $attemptobj1->get_slots(0); + $slots1b = $attemptobj2->get_slots(0); + $slots2a = $attemptobj1->get_slots(1); + $slots2b = $attemptobj2->get_slots(1); + + // Get question order for each section in both attempts. + $order1a = array_map(fn($slot) => $attemptobj1->get_question_attempt($slot)->get_question()->id, $slots1a); + $order1b = array_map(fn($slot) => $attemptobj2->get_question_attempt($slot)->get_question()->id, $slots1b); + $order2a = array_map(fn($slot) => $attemptobj1->get_question_attempt($slot)->get_question()->id, $slots2a); + $order2b = array_map(fn($slot) => $attemptobj2->get_question_attempt($slot)->get_question()->id, $slots2b); + + // Assert shuffled section is different, non-shuffled is the same. + $this->assertNotEquals($order1a, $order1b, 'Shuffled section should have different order between attempts.'); + $this->assertEquals($order2a, $order2b, 'Non-shuffled section should have same order between attempts.'); + } }