1
0
mirror of https://github.com/moodle/moodle.git synced 2025-04-07 09:23:31 +02:00

MDL-82592 quiz grades: 'setup for sections' handling of descriptions

This commit is contained in:
Tim Hunt 2024-07-26 10:57:05 +01:00
parent 1a33da6637
commit 49e09cdbfe
4 changed files with 79 additions and 1 deletions

@ -85,6 +85,16 @@ class create_grade_item_per_section extends external_api {
$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;
@ -93,7 +103,9 @@ class create_grade_item_per_section extends external_api {
}
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();

@ -1185,6 +1185,10 @@ class structure {
$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.

@ -249,6 +249,52 @@ final class grade_items_test extends externallib_advanced_testcase {
$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();

@ -16,6 +16,8 @@
namespace mod_quiz;
use core\exception\coding_exception;
defined('MOODLE_INTERNAL') || die();
global $CFG;
@ -939,6 +941,20 @@ class structure_test extends \advanced_testcase {
$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.
*/