Skip to content

Commit

Permalink
MDL-82592 quiz grades: 'setup for sections' handling of descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
timhunt committed Jul 26, 2024
1 parent 1a33da6 commit 49e09cd
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
14 changes: 13 additions & 1 deletion mod/quiz/classes/external/create_grade_item_per_section.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ public static function execute(int $quizid): void {

$gradeitemsids = [];
foreach ($structure->get_sections() as $section) {
// Only create a grade item for sections that contain at least one real question (not description).
$hasrealquestion = false;
foreach ($structure->get_slots_in_section($section->id) as $slot) {
$hasrealquestion = $hasrealquestion || $structure->is_real_question($slot);
}
if (!$hasrealquestion) {
continue;
}

// Grade item required. Create it.
$gradeitem = new stdClass();
$gradeitem->quizid = $quizid;
$gradeitem->name = $section->heading;
Expand All @@ -93,7 +103,9 @@ public static function execute(int $quizid): void {
}

foreach ($structure->get_slots() as $slot) {
$structure->update_slot_grade_item($slot, $gradeitemsids[$slot->section->id]);
if ($structure->is_real_question($slot->slot)) {
$structure->update_slot_grade_item($slot, $gradeitemsids[$slot->section->id]);
}
}

$transaction->allow_commit();
Expand Down
4 changes: 4 additions & 0 deletions mod/quiz/classes/structure.php
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,10 @@ public function update_slot_grade_item(stdClass $slot, ?int $gradeitemid): bool
$gradeitemid = null;
}

if ($gradeitemid !== null && !$this->is_real_question($slot->slot)) {
throw new coding_exception('Cannot set a grade item for a question that is ungraded.');
}

if ($slot->quizgradeitemid !== null) {
// Object $slot likely comes from the database, which means int may be
// represented as a string, which breaks the next test, so fix up.
Expand Down
46 changes: 46 additions & 0 deletions mod/quiz/tests/external/grade_items_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,52 @@ public function test_create_grade_item_per_section_works(): void {
$this->assertEquals($gradeitems[1]->id, $structure->get_slot_by_number(3)->quizgradeitemid);
}

public function test_create_grade_item_per_section_with_descriptions(): void {
global $SITE;
$this->resetAfterTest();
$this->setAdminUser();

// Create a quiz with no grade items yet, but two sections.
/** @var \mod_quiz_generator $quizgenerator */
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
$quiz = $quizgenerator->create_instance(['course' => $SITE->id]);

// Create three questions.
/** @var core_question_generator $questiongenerator */
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
$cat = $questiongenerator->create_question_category();
$desc1 = $questiongenerator->create_question('description', null, ['category' => $cat->id]);
$desc2 = $questiongenerator->create_question('description', null, ['category' => $cat->id]);
$saq1 = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]);

// Add them to the quiz.
quiz_add_quiz_question($desc1->id, $quiz, 1);
quiz_add_quiz_question($desc2->id, $quiz, 2);
quiz_add_quiz_question($saq1->id, $quiz, 2, 7);

// Create two sections.
$quizobj = quiz_settings::create($quiz->id);
$structure = $quizobj->get_structure();
$defaultsection = array_values($structure->get_sections())[0];
$structure->set_section_heading($defaultsection->id, 'Introduction');
$structure->add_section_heading(2, 'The question');

// Call the method we are testing.
create_grade_item_per_section::execute($quizobj->get_quizid());

// Verify.
$structure = $quizobj->get_structure();

$gradeitems = array_values($structure->get_grade_items());
$this->assertCount(1, $gradeitems);
$this->assertEquals('The question', $gradeitems[0]->name);
$this->assertEquals(1, $gradeitems[0]->sortorder);

$this->assertNull($structure->get_slot_by_number(1)->quizgradeitemid);
$this->assertNull($structure->get_slot_by_number(2)->quizgradeitemid);
$this->assertEquals($gradeitems[0]->id, $structure->get_slot_by_number(3)->quizgradeitemid);
}

public function test_create_grade_item_per_section_service_checks_permissions(): void {
global $SITE;
$this->resetAfterTest();
Expand Down
16 changes: 16 additions & 0 deletions mod/quiz/tests/structure_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

namespace mod_quiz;

use core\exception\coding_exception;

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

global $CFG;
Expand Down Expand Up @@ -939,6 +941,20 @@ public function test_update_slot_grade_item(): void {
$this->assertFalse($structure->update_slot_grade_item($slot, null));
}

public function test_cannot_set_nonnull_slot_grade_item_for_description(): void {
$quizobj = $this->create_test_quiz([
['Info', 1, 'description'],
]);
/** @var \mod_quiz_generator $quizgenerator */
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
$gradeitem = $quizgenerator->create_grade_item(
['quizid' => $quizobj->get_quizid(), 'name' => 'Awesomeness!']);
$structure = structure::create_for_quiz($quizobj);

$this->expectException(coding_exception::class);
$structure->update_slot_grade_item($structure->get_slot_by_number(1), $gradeitem->id);
}

/**
* Test for can_add_random_questions.
*/
Expand Down

0 comments on commit 49e09cd

Please sign in to comment.