diff --git a/mod/quiz/tests/behat/behat_mod_quiz.php b/mod/quiz/tests/behat/behat_mod_quiz.php index c23c318df0f..2aa850178bd 100644 --- a/mod/quiz/tests/behat/behat_mod_quiz.php +++ b/mod/quiz/tests/behat/behat_mod_quiz.php @@ -850,15 +850,29 @@ class behat_mod_quiz extends behat_question_base { * @param string $username the username of the user that will attempt. * @param string $quizname the name of the quiz the user will attempt. * @param TableNode $attemptinfo information about the questions to add, as above. + * @param string|null $timefinish if specified, the attempt will be submitted with this * @Given /^user "([^"]*)" has attempted "([^"]*)" with responses:$/ + * @Given /^user "([^"]*)" has attempted "([^"]*)" with responses submitting "([^"]*)":$/ */ - public function user_has_attempted_with_responses($username, $quizname, TableNode $attemptinfo) { + public function user_has_attempted_with_responses($username, $quizname, TableNode $attemptinfo, $timefinish = null) { global $DB; /** @var mod_quiz_generator $quizgenerator */ $quizgenerator = behat_util::get_data_generator()->get_plugin_generator('mod_quiz'); - $quizid = $DB->get_field('quiz', 'id', ['name' => $quizname], MUST_EXIST); + $quiz = $DB->get_record('quiz', ['name' => $quizname], 'id, timeclose', MUST_EXIST); + $quizid = $quiz->id; + $timeclose = $quiz->timeclose; + + // If timefinish is provided, check against timeclose. + if ($timefinish !== null) { + if ($timeclose && $timefinish > $timeclose) { + throw new ExpectationException( + "Attempt submission cannot be after the time the quiz closed.", + $this->getSession() + ); + } + } $user = $DB->get_record('user', ['username' => $username], '*', MUST_EXIST); list($forcedrandomquestions, $forcedvariants) = @@ -870,7 +884,7 @@ class behat_mod_quiz extends behat_question_base { $attempt = $quizgenerator->create_attempt($quizid, $user->id, $forcedrandomquestions, $forcedvariants); - $quizgenerator->submit_responses($attempt->id, $responses, false, true); + $quizgenerator->submit_responses($attempt->id, $responses, false, true, $timefinish); $this->set_user(); } diff --git a/mod/quiz/tests/behat/quiz_feedback.feature b/mod/quiz/tests/behat/quiz_feedback.feature index ed4185780b1..d8738d88b05 100644 --- a/mod/quiz/tests/behat/quiz_feedback.feature +++ b/mod/quiz/tests/behat/quiz_feedback.feature @@ -83,3 +83,68 @@ Feature: Enable deferred or immediate feedback for quiz And the "True" "field" should be disabled And the "False" "field" should be disabled And "Check Question 1" "button" should not exist + + Scenario Outline: Responses, answers and feedback are displayed after attempting a quiz depending on time finished + Given the following "activity" exists: + | activity | quiz | + | name | Quiz 1 | + | course | C1 | + | idnumber | quiz1 | + | maxmarksimmediately | 0 | + | specificfeedbackimmediately | 0 | + | rightanswerimmediately | 0 | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + And user "student1" has attempted "Quiz 1" with responses submitting "": + | slot | response | + | 1 | True | + When I am on the "Quiz 1" "quiz activity" page logged in as student1 + And I click on "Review" "link" + Then I should see "You should have selected true." + And I see "This is the right answer." + And I see "The correct answer is 'True'." + And the following exist in the "quizreviewsummary" table: + | -1- | -2- | + | Marks | 1.00/1.00 | + | Grade | 100.00 out of 100.00 | + + Examples: + | timefinish | visibility | + | ## 1 minute ago ## | should not | + | ## 2 minute ago ## | should | + + Scenario Outline: Responses, answers and feedback cannot be reviewed after attempting a quiz as long as quiz is open + Given the following "activity" exists: + | activity | quiz | + | name | Quiz 1 | + | course | C1 | + | idnumber | quiz1 | + | timeclose | | + | generalfeedbackimmediately | 0 | + | attemptimmediately | 0 | + | overallfeedbackopen | 0 | + | rightansweropen | 0 | + | generalfeedbackopen | 0 | + | specificfeedbackopen | 0 | + | marksopen | 0 | + | maxmarksopen | 0 | + | correctnessopen | 0 | + | attemptopen | 0 | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + And user "student1" has attempted "Quiz 1" with responses: + | slot | response | + | 1 | True | + When I am on the "Quiz 1" "quiz activity" page logged in as student1 + # Confirm the Review link visibility. Should exist if quiz is closed, otherwise, it shouldn't exist. + Then "Review" "link" exist + # Confirm the `Available` text and close date visibility. Should only be visible while quiz is open. + And I see "Available" + And I see "##tomorrow##%d/%m/%y##" + + Examples: + | quizclosedate | reviewlinkvisibility | availabilityvisibility | + | ## tomorrow ## | should not | should | + | ## yesterday ## | should | should not | diff --git a/mod/quiz/tests/generator/lib.php b/mod/quiz/tests/generator/lib.php index da94f9b80b4..ca17457eaa9 100644 --- a/mod/quiz/tests/generator/lib.php +++ b/mod/quiz/tests/generator/lib.php @@ -151,8 +151,9 @@ class mod_quiz_generator extends testing_module_generator { * @param bool $checkbutton if simulate a click on the check button for each question, else simulate save. * This should only be used with behaviours that have a check button. * @param bool $finishattempt if true, the attempt will be submitted. + * @param int|null $timefinish the time to set as the time finished for the attempt. */ - public function submit_responses($attemptid, array $responses, $checkbutton, $finishattempt) { + public function submit_responses($attemptid, array $responses, $checkbutton, $finishattempt, ?int $timefinish = null) { $questiongenerator = $this->datagenerator->get_plugin_generator('core_question'); $attemptobj = quiz_attempt::create($attemptid); @@ -181,7 +182,9 @@ class mod_quiz_generator extends testing_module_generator { } if ($finishattempt) { - $attemptobj->process_submit(time(), false); + // If a timefinish is not specified, use the current time. + $timefinish = $timefinish ?? time(); + $attemptobj->process_submit($timefinish, false); $attemptobj->process_grade_submission(time()); } }