MDL-83541 qtypes: Define excluded hash fields and test hints
This commit is contained in:
committed by
Huong Nguyen
parent
85d85a6a25
commit
2de34d5c0e
@@ -113,4 +113,46 @@ class restore_qtype_calculated_plugin extends restore_qtype_plugin {
|
||||
$newitemid = $DB->insert_record('question_calculated_options', $data);
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function convert_backup_to_questiondata(array $backupdata): \stdClass {
|
||||
$questiondata = parent::convert_backup_to_questiondata($backupdata);
|
||||
$qtype = $questiondata->qtype;
|
||||
foreach ($backupdata["plugin_qtype_{$qtype}_question"]['calculated_records']['calculated_record'] as $record) {
|
||||
foreach ($questiondata->options->answers as &$answer) {
|
||||
if ($answer->id == $record['answer']) {
|
||||
$answer->tolerance = $record['tolerance'];
|
||||
$answer->tolerancetype = $record['tolerancetype'];
|
||||
$answer->correctanswerlength = $record['correctanswerlength'];
|
||||
$answer->correctanswerformat = $record['correctanswerformat'];
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($backupdata["plugin_qtype_{$qtype}_question"]['calculated_options'])) {
|
||||
$questiondata->options = (object) array_merge(
|
||||
(array) $questiondata->options,
|
||||
$backupdata["plugin_qtype_{$qtype}_question"]['calculated_options']['calculated_option'][0],
|
||||
);
|
||||
}
|
||||
return $questiondata;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function define_excluded_identity_hash_fields(): array {
|
||||
return [
|
||||
// These option fields are present in the database, but are only used by calculatedmulti.
|
||||
'/options/synchronize',
|
||||
'/options/single',
|
||||
'/options/shuffleanswers',
|
||||
'/options/correctfeedback',
|
||||
'/options/correctfeedbackformat',
|
||||
'/options/partiallycorrectfeedback',
|
||||
'/options/partiallycorrectfeedbackformat',
|
||||
'/options/incorrectfeedback',
|
||||
'/options/incorrectfeedbackformat',
|
||||
'/options/answernumbering',
|
||||
'/options/shownumcorrect',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ class qtype_calculated_test_helper extends question_test_helper {
|
||||
$fromform->defaultmark = 1.0;
|
||||
$fromform->generalfeedback = 'Generalfeedback: {={a} + {b}} is the right answer.';
|
||||
|
||||
$fromform->unitrole = '3';
|
||||
$fromform->unitrole = '0';
|
||||
$fromform->unitpenalty = 0.1;
|
||||
$fromform->unitgradingtypes = '1';
|
||||
$fromform->unitsleft = '0';
|
||||
@@ -187,6 +187,20 @@ class qtype_calculated_test_helper extends question_test_helper {
|
||||
|
||||
$fromform->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
$fromform->hint = [
|
||||
[
|
||||
'text' => 'Add',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
$fromform->unit = [
|
||||
'x',
|
||||
];
|
||||
$fromform->multiplier = [
|
||||
'1.0',
|
||||
];
|
||||
|
||||
return $fromform;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,12 +104,18 @@ final class question_type_test extends \advanced_testcase {
|
||||
$this->assertEquals($question->createdby, $questiondata->modifiedby);
|
||||
$this->assertEquals('', $questiondata->idnumber);
|
||||
$this->assertEquals($syscontext->id, $questiondata->contextid);
|
||||
$this->assertEquals([], $questiondata->hints);
|
||||
$this->assertCount(1, $questiondata->hints);
|
||||
$hint = array_pop($questiondata->hints);
|
||||
$this->assertEquals('Add', $hint->hint);
|
||||
$this->assertEquals(FORMAT_HTML, $hint->hintformat);
|
||||
|
||||
// Options.
|
||||
$this->assertEquals($questiondata->id, $questiondata->options->question);
|
||||
$this->assertEquals([], $questiondata->options->units);
|
||||
$this->assertEquals(qtype_numerical::UNITNONE, $questiondata->options->showunits);
|
||||
$this->assertCount(1, $questiondata->options->units);
|
||||
$unit = array_pop($questiondata->options->units);
|
||||
$this->assertEquals($unit->unit, 'x');
|
||||
$this->assertEquals($unit->multiplier, '1.0');
|
||||
$this->assertEquals(qtype_numerical::UNITOPTIONAL, $questiondata->options->showunits);
|
||||
$this->assertEquals(0, $questiondata->options->unitgradingtype); // Unit role is none, so this is 0.
|
||||
$this->assertEquals($fromform->unitpenalty, $questiondata->options->unitpenalty);
|
||||
$this->assertEquals($fromform->unitsleft, $questiondata->options->unitsleft);
|
||||
|
||||
+5
@@ -69,4 +69,9 @@ class restore_qtype_calculatedmulti_plugin extends restore_qtype_calculated_plug
|
||||
}
|
||||
return $result ? $result : $answer;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function define_excluded_identity_hash_fields(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,4 +127,95 @@ class qtype_calculatedmulti_test_helper extends question_test_helper {
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the form data for a question with a single response.
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function get_calculatedmulti_question_form_data_singleresponse(): stdClass {
|
||||
question_bank::load_question_definition_classes('calculated');
|
||||
$fromform = new stdClass();
|
||||
|
||||
$fromform->name = 'Simple sum';
|
||||
$fromform->questiontext['text'] = 'What is {a} + {b}?';
|
||||
$fromform->questiontext['format'] = FORMAT_HTML;
|
||||
$fromform->defaultmark = 1.0;
|
||||
$fromform->generalfeedback['text'] = 'Generalfeedback: {={a} + {b}} is the right answer.';
|
||||
$fromform->generalfeedback['format'] = FORMAT_HTML;
|
||||
|
||||
$fromform->unitrole = '3';
|
||||
$fromform->unitpenalty = 0.1;
|
||||
$fromform->unitgradingtypes = '1';
|
||||
$fromform->unitsleft = '0';
|
||||
$fromform->nounits = 1;
|
||||
$fromform->multiplier = [];
|
||||
$fromform->multiplier[0] = '1.0';
|
||||
$fromform->synchronize = 0;
|
||||
$fromform->answernumbering = 0;
|
||||
$fromform->shuffleanswers = 0;
|
||||
$fromform->single = 1;
|
||||
$fromform->correctfeedback['text'] = 'Very good';
|
||||
$fromform->correctfeedback['format'] = FORMAT_HTML;
|
||||
$fromform->partiallycorrectfeedback['text'] = 'Mostly good';
|
||||
$fromform->partiallycorrectfeedback['format'] = FORMAT_HTML;
|
||||
$fromform->incorrectfeedback['text'] = 'Completely Wrong';
|
||||
$fromform->incorrectfeedback['format'] = FORMAT_HTML;
|
||||
$fromform->shownumcorrect = 1;
|
||||
|
||||
$fromform->noanswers = 6;
|
||||
$fromform->answer = [];
|
||||
$fromform->answer[0]['text'] = '{a} + {b}';
|
||||
$fromform->answer[0]['format'] = FORMAT_HTML;
|
||||
$fromform->answer[1]['text'] = '{a} - {b}';
|
||||
$fromform->answer[1]['format'] = FORMAT_HTML;
|
||||
$fromform->answer[2]['text'] = '*';
|
||||
$fromform->answer[2]['format'] = FORMAT_HTML;
|
||||
|
||||
$fromform->fraction = [];
|
||||
$fromform->fraction[0] = '1.0';
|
||||
$fromform->fraction[1] = '0.0';
|
||||
$fromform->fraction[2] = '0.0';
|
||||
|
||||
$fromform->tolerance = [];
|
||||
$fromform->tolerance[0] = 0.001;
|
||||
$fromform->tolerance[1] = 0.001;
|
||||
$fromform->tolerance[2] = 0;
|
||||
|
||||
$fromform->tolerancetype[0] = 1;
|
||||
$fromform->tolerancetype[1] = 1;
|
||||
$fromform->tolerancetype[2] = 1;
|
||||
|
||||
$fromform->correctanswerlength[0] = 2;
|
||||
$fromform->correctanswerlength[1] = 2;
|
||||
$fromform->correctanswerlength[2] = 2;
|
||||
|
||||
$fromform->correctanswerformat[0] = 1;
|
||||
$fromform->correctanswerformat[1] = 1;
|
||||
$fromform->correctanswerformat[2] = 1;
|
||||
|
||||
$fromform->feedback = [];
|
||||
$fromform->feedback[0] = [];
|
||||
$fromform->feedback[0]['format'] = FORMAT_HTML;
|
||||
$fromform->feedback[0]['text'] = 'Very good.';
|
||||
|
||||
$fromform->feedback[1] = [];
|
||||
$fromform->feedback[1]['format'] = FORMAT_HTML;
|
||||
$fromform->feedback[1]['text'] = 'Add. not subtract!';
|
||||
|
||||
$fromform->feedback[2] = [];
|
||||
$fromform->feedback[2]['format'] = FORMAT_HTML;
|
||||
$fromform->feedback[2]['text'] = 'Completely wrong.';
|
||||
|
||||
$fromform->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
$fromform->hint = [
|
||||
[
|
||||
'text' => 'Add',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
return $fromform;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,13 @@ class qtype_calculatedsimple_test_helper extends question_test_helper {
|
||||
$form->definition[19] = '1-0-b';
|
||||
$form->definition[20] = '1-0-a';
|
||||
|
||||
$form->hint = [
|
||||
[
|
||||
'text' => 'Add',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
$form->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
return $form;
|
||||
|
||||
@@ -88,7 +88,7 @@ final class question_type_test extends \advanced_testcase {
|
||||
$actualquestiondata = end($actualquestionsdata);
|
||||
|
||||
foreach ($questiondata as $property => $value) {
|
||||
if (!in_array($property, array('id', 'timemodified', 'timecreated', 'options', 'idnumber'))) {
|
||||
if (!in_array($property, ['id', 'timemodified', 'timecreated', 'options', 'idnumber', 'hints'])) {
|
||||
$this->assertEquals($value, $actualquestiondata->$property);
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,11 @@ final class question_type_test extends \advanced_testcase {
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertCount(1, $actualquestiondata->hints);
|
||||
$hint = array_pop($actualquestiondata->hints);
|
||||
$this->assertEquals($formdata->hint[0]['text'], $hint->hint);
|
||||
$this->assertEquals($formdata->hint[0]['format'], $hint->hintformat);
|
||||
|
||||
$datasetloader = new qtype_calculated_dataset_loader($actualquestiondata->id);
|
||||
|
||||
$this->assertEquals(10, $datasetloader->get_number_of_items());
|
||||
|
||||
+25
@@ -166,4 +166,29 @@ class restore_qtype_ddimageortext_plugin extends restore_qtype_plugin {
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function convert_backup_to_questiondata(array $backupdata): \stdClass {
|
||||
$questiondata = parent::convert_backup_to_questiondata($backupdata);
|
||||
$questiondata->options->drags = array_map(
|
||||
fn($drag) => (object) $drag,
|
||||
$backupdata['plugin_qtype_ddimageortext_question']['drags']['drag'] ?? [],
|
||||
);
|
||||
$questiondata->options->drops = array_map(
|
||||
fn($drop) => (object) $drop,
|
||||
$backupdata['plugin_qtype_ddimageortext_question']['drops']['drop'] ?? [],
|
||||
);
|
||||
return $questiondata;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function define_excluded_identity_hash_fields(): array {
|
||||
return [
|
||||
'/options/drags/id',
|
||||
'/options/drags/questionid',
|
||||
'/options/drops/id',
|
||||
'/options/drops/questionid',
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,4 +168,28 @@ class restore_qtype_ddmarker_plugin extends restore_qtype_plugin {
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function convert_backup_to_questiondata(array $backupdata): \stdClass {
|
||||
$questiondata = parent::convert_backup_to_questiondata($backupdata);
|
||||
$questiondata->options->drags = array_map(
|
||||
fn($drag) => (object) $drag,
|
||||
$backupdata['plugin_qtype_ddmarker_question']['drags']['drag'] ?? [],
|
||||
);
|
||||
$questiondata->options->drops = array_map(
|
||||
fn($drop) => (object) $drop,
|
||||
$backupdata['plugin_qtype_ddmarker_question']['drops']['drop'] ?? [],
|
||||
);
|
||||
return $questiondata;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function define_excluded_identity_hash_fields(): array {
|
||||
return [
|
||||
'/options/drags/id',
|
||||
'/options/drags/questionid',
|
||||
'/options/drops/id',
|
||||
'/options/drops/questionid',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,13 @@ class qtype_ddwtos_test_helper extends question_test_helper {
|
||||
$fromform->penalty = 0.3333333;
|
||||
$fromform->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
$fromform->hint = [
|
||||
[
|
||||
'text' => 'Fast',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
return $fromform;
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,13 @@ class qtype_gapselect_test_helper extends question_test_helper {
|
||||
$fromform->penalty = 0.3333333;
|
||||
$fromform->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
$fromform->hint = [
|
||||
[
|
||||
'text' => 'Cat',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
return $fromform;
|
||||
}
|
||||
|
||||
|
||||
@@ -246,4 +246,23 @@ class restore_qtype_match_plugin extends restore_qtype_plugin {
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function convert_backup_to_questiondata(array $backupdata): \stdClass {
|
||||
$questiondata = parent::convert_backup_to_questiondata($backupdata);
|
||||
$questiondata->options = (object) $backupdata["plugin_qtype_match_question"]['matchoptions'][0];
|
||||
$questiondata->options->subquestions = array_map(
|
||||
fn($match) => (object) $match,
|
||||
$backupdata["plugin_qtype_match_question"]['matches']['match'] ?? [],
|
||||
);
|
||||
return $questiondata;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function define_excluded_identity_hash_fields(): array {
|
||||
return [
|
||||
'/options/subquestions/id',
|
||||
'/options/subquestions/questionid',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +131,13 @@ class qtype_match_test_helper extends question_test_helper {
|
||||
|
||||
$q->noanswers = 4;
|
||||
|
||||
$q->hint = [
|
||||
[
|
||||
'text' => 'Frog and newt are the same',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ final class question_type_test extends \advanced_testcase {
|
||||
|
||||
foreach ($questiondata as $property => $value) {
|
||||
if (!in_array($property, ['id', 'timemodified', 'timecreated', 'options', 'stamp',
|
||||
'versionid', 'questionbankentryid'])) {
|
||||
'versionid', 'questionbankentryid', 'hints'])) {
|
||||
if (!empty($actualquestiondata)) {
|
||||
$this->assertEquals($value, $actualquestiondata->$property);
|
||||
}
|
||||
@@ -201,6 +201,11 @@ final class question_type_test extends \advanced_testcase {
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertCount(1, $actualquestiondata->hints);
|
||||
$hint = array_pop($actualquestiondata->hints);
|
||||
$this->assertEquals($formdata->hint[0]['text'], $hint->hint);
|
||||
$this->assertEquals($formdata->hint[0]['format'], $hint->hintformat);
|
||||
|
||||
$this->assertObjectHasProperty('subquestions', $actualquestiondata->options);
|
||||
|
||||
$subqpropstoignore = array('id');
|
||||
|
||||
@@ -199,4 +199,19 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
||||
return implode(',', $resultarr);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function define_excluded_identity_hash_fields(): array {
|
||||
return [
|
||||
'/options/sequence',
|
||||
'/options/question',
|
||||
];
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function remove_excluded_question_data(stdClass $questiondata, array $excludefields = []): stdClass {
|
||||
if (isset($questiondata->options->questions)) {
|
||||
unset($questiondata->options->questions);
|
||||
}
|
||||
return parent::remove_excluded_question_data($questiondata, $excludefields);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,4 +80,18 @@ class restore_qtype_numerical_plugin extends restore_qtype_plugin {
|
||||
$newitemid = $DB->insert_record('question_numerical', $data);
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function convert_backup_to_questiondata(array $backupdata): \stdClass {
|
||||
$questiondata = parent::convert_backup_to_questiondata($backupdata);
|
||||
foreach ($backupdata['plugin_qtype_numerical_question']['numerical_records']['numerical_record'] as $record) {
|
||||
foreach ($questiondata->options->answers as &$answer) {
|
||||
if ($answer->id == $record['answer']) {
|
||||
$answer->tolerance = $record['tolerance'];
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $questiondata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +164,13 @@ class qtype_numerical_test_helper extends question_test_helper {
|
||||
$form->qtype = 'numerical';
|
||||
$form->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
$form->hint = [
|
||||
[
|
||||
'text' => 'Just over 3',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,12 @@ class qtype_shortanswer_test_helper extends question_test_helper {
|
||||
array('text' => 'That is a bad answer.', 'format' => FORMAT_HTML),
|
||||
);
|
||||
$form->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
|
||||
|
||||
$form->hint = [
|
||||
[
|
||||
'text' => 'Rhymes with dog',
|
||||
'format' => FORMAT_HTML,
|
||||
],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ final class question_type_test extends \advanced_testcase {
|
||||
$actualquestiondata = end($actualquestionsdata);
|
||||
|
||||
foreach ($questiondata as $property => $value) {
|
||||
if (!in_array($property, array('id', 'timemodified', 'timecreated', 'options'))) {
|
||||
if (!in_array($property, ['id', 'timemodified', 'timecreated', 'options', 'hints'])) {
|
||||
$this->assertEquals($value, $actualquestiondata->$property);
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,11 @@ final class question_type_test extends \advanced_testcase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertCount(1, $actualquestiondata->hints);
|
||||
$hint = array_pop($actualquestiondata->hints);
|
||||
$this->assertEquals($formdata->hint[0]['text'], $hint->hint);
|
||||
$this->assertEquals($formdata->hint[0]['format'], $hint->hintformat);
|
||||
}
|
||||
|
||||
public function test_question_saving_trims_answers(): void {
|
||||
|
||||
@@ -93,4 +93,13 @@ class restore_qtype_truefalse_plugin extends restore_qtype_plugin {
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function define_excluded_identity_hash_fields(): array {
|
||||
return [
|
||||
'/options/trueanswer',
|
||||
'/options/falseanswer',
|
||||
'/options/question',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user