Merge branch 'MDL-64464' of https://github.com/timhunt/moodle
This commit is contained in:
@@ -267,8 +267,8 @@ class qtype_ddimageortext_edit_form extends qtype_ddtoimage_edit_form_base {
|
||||
for ($dragindex = 0; $dragindex < $data['noitems']; $dragindex++) {
|
||||
$label = $data['draglabel'][$dragindex];
|
||||
if ($data['drags'][$dragindex]['dragitemtype'] == 'word') {
|
||||
$allowedtags = '<br><sub><sup><b><i><strong><em>';
|
||||
$errormessage = get_string('formerror_disallowedtags', 'qtype_ddimageortext');
|
||||
$allowedtags = '<br><sub><sup><b><i><strong><em><span>';
|
||||
$errormessage = get_string('formerror_disallowedtags', 'qtype_ddimageortext', s($allowedtags));
|
||||
} else {
|
||||
$allowedtags = '';
|
||||
$errormessage = get_string('formerror_noallowedtags', 'qtype_ddimageortext');
|
||||
|
||||
@@ -37,7 +37,7 @@ $string['draggableword'] = 'Draggable text';
|
||||
$string['dropbackground'] = 'Background image for dragging markers onto';
|
||||
$string['dropzone'] = 'Drop zone {$a}';
|
||||
$string['dropzoneheader'] = 'Drop zones';
|
||||
$string['formerror_disallowedtags'] = 'Sorry, HTML tags are not allowed in draggable text.';
|
||||
$string['formerror_disallowedtags'] = 'Only "{$a}" tags are allowed in this draggable text.';
|
||||
$string['formerror_noallowedtags'] = 'HTML tags are not allowed in this text which is the alt text for a draggable image.';
|
||||
$string['formerror_noytop'] = 'You must provide a value for the y coordinate for the top left corner of this drop area. You can drag and drop the drop area above to set the coordinates or enter them manually here.';
|
||||
$string['formerror_noxleft'] = 'You must provide a value for the x coordinate for the top left corner of this drop area. You can drag and drop the drop area above to set the coordinates or enter them manually here.';
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for the drag-and-drop onto image edit form.
|
||||
*
|
||||
* @package qtype_ddimageortext
|
||||
* @copyright 2019 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
||||
require_once($CFG->dirroot . '/question/type/edit_question_form.php');
|
||||
require_once($CFG->dirroot . '/question/type/ddimageortext/edit_ddimageortext_form.php');
|
||||
|
||||
/**
|
||||
* Unit tests for the drag-and-drop onto image edit form.
|
||||
*
|
||||
* @copyright 2019 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_ddimageortext_edit_form_test extends advanced_testcase {
|
||||
/**
|
||||
* Helper method.
|
||||
*
|
||||
* @return array with two elements:
|
||||
* question_edit_form great a question form instance that can be tested.
|
||||
* stdClass the question category.
|
||||
*/
|
||||
protected function get_form() {
|
||||
$this->setAdminUser();
|
||||
$this->resetAfterTest();
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$category = question_make_default_categories(array($syscontext));
|
||||
$fakequestion = new stdClass();
|
||||
$fakequestion->qtype = 'ddimageortext';
|
||||
$fakequestion->contextid = $syscontext->id;
|
||||
$fakequestion->createdby = 2;
|
||||
$fakequestion->category = $category->id;
|
||||
$fakequestion->questiontext = 'Test question';
|
||||
$fakequestion->options = new stdClass();
|
||||
$fakequestion->options->answers = array();
|
||||
$fakequestion->formoptions = new stdClass();
|
||||
$fakequestion->formoptions->movecontext = null;
|
||||
$fakequestion->formoptions->repeatelements = true;
|
||||
$fakequestion->inputs = null;
|
||||
|
||||
$form = new qtype_ddimageortext_edit_form(new moodle_url('/'), $fakequestion, $category,
|
||||
new question_edit_contexts($syscontext));
|
||||
|
||||
return [$form, $category];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the form correctly validates the HTML allowed in items.
|
||||
*/
|
||||
public function test_item_validation() {
|
||||
list($form, $category) = $this->get_form();
|
||||
|
||||
$submitteddata = [
|
||||
'category' => $category->id,
|
||||
'bgimage' => '',
|
||||
'nodropzone' => 0,
|
||||
'noitems' => 5,
|
||||
'drags' => [
|
||||
['dragitemtype' => 'image'],
|
||||
['dragitemtype' => 'image'],
|
||||
['dragitemtype' => 'word'],
|
||||
['dragitemtype' => 'word'],
|
||||
['dragitemtype' => 'word'],
|
||||
],
|
||||
'draglabel' => [
|
||||
'frog',
|
||||
'<b>toad</b>',
|
||||
'cat',
|
||||
'<span lang="fr"><b>chien</b></span>',
|
||||
'<textarea>evil!</textarea>',
|
||||
],
|
||||
];
|
||||
|
||||
$errors = $form->validation($submitteddata, []);
|
||||
|
||||
$this->assertArrayNotHasKey('drags[0]', $errors);
|
||||
$this->assertEquals('HTML tags are not allowed in this text which is the alt text for a draggable image.',
|
||||
$errors['drags[1]']);
|
||||
$this->assertArrayNotHasKey('drags[2]', $errors);
|
||||
$this->assertArrayNotHasKey('drags[3]', $errors);
|
||||
$this->assertEquals('Only "<br><sub><sup><b><i><strong><em><span>" ' .
|
||||
'tags are allowed in this draggable text.', $errors['drags[4]']);
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
class qtype_ddimageortext_test_helper extends question_test_helper {
|
||||
public function get_test_questions() {
|
||||
return array('fox', 'maths', 'xsection');
|
||||
return array('fox', 'maths', 'xsection', 'mixedlang');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,4 +248,39 @@ class qtype_ddimageortext_test_helper extends question_test_helper {
|
||||
|
||||
return $fromform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a test question where the drag items are a different language than the main question text.
|
||||
*
|
||||
* @return qtype_ddimageortext_question
|
||||
*/
|
||||
public function make_ddimageortext_question_mixedlang() {
|
||||
question_bank::load_question_definition_classes('ddimageortext');
|
||||
$dd = new qtype_ddimageortext_question();
|
||||
|
||||
test_question_maker::initialise_a_question($dd);
|
||||
|
||||
$dd->name = 'Question about French in English.';
|
||||
$dd->questiontext = '<p>Complete the blanks in this sentence.</p>' .
|
||||
'<p lang="fr">J\'ai perdu [[1]] plume de [[2]] tante - l\'avez-vous vue?</p>';
|
||||
$dd->generalfeedback = 'This sentence uses each letter of the alphabet.';
|
||||
$dd->qtype = question_bank::get_qtype('ddimageortext');
|
||||
|
||||
$dd->shufflechoices = true;
|
||||
|
||||
test_question_maker::set_standard_combined_feedback_fields($dd);
|
||||
|
||||
$dd->choices = $this->make_choice_structure(array(
|
||||
new qtype_ddimageortext_drag_item('<span lang="fr">la</span>', 1, 1),
|
||||
new qtype_ddimageortext_drag_item('<span lang="fr">ma</span>', 2, 1),
|
||||
));
|
||||
|
||||
$dd->places = $this->make_place_structure(array(
|
||||
new qtype_ddimageortext_drop_zone('', 1, 1),
|
||||
new qtype_ddimageortext_drop_zone('', 2, 1)
|
||||
));
|
||||
$dd->rightchoices = array(1 => 1, 2 => 2);
|
||||
|
||||
return $dd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,4 +854,20 @@ class qtype_ddimageortext_walkthrough_test extends qbehaviour_walkthrough_test_b
|
||||
$this->check_current_state(question_state::$gradedright);
|
||||
$this->check_current_mark(3);
|
||||
}
|
||||
|
||||
public function test_mixed_lang_rendering() {
|
||||
|
||||
// Create a mixe drag-and-drop question.
|
||||
$dd = test_question_maker::make_question('ddimageortext', 'mixedlang');
|
||||
$dd->shufflechoices = false;
|
||||
$this->start_attempt_at_question($dd, 'interactive', 1);
|
||||
|
||||
// Check the initial state.
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_current_output(
|
||||
new question_pattern_expectation('~<div class="group1 draghome choice1"><span lang="fr">la</span></div>~'),
|
||||
new question_pattern_expectation('~<div class="group1 draghome choice2"><span lang="fr">ma</span></div>~')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
require_once($CFG->dirroot.'/question/type/ddimageortext/edit_ddtoimage_form_base.php');
|
||||
require_once($CFG->dirroot.'/question/type/ddmarker/shapes.php');
|
||||
|
||||
define('QTYPE_DDMARKER_ALLOWED_TAGS_IN_MARKER', '<br><i><em><b><strong><sup><sub><u>');
|
||||
define('QTYPE_DDMARKER_ALLOWED_TAGS_IN_MARKER', '<br><i><em><b><strong><sup><sub><u><span>');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for the drag-and-drop markers edit form.
|
||||
*
|
||||
* @package qtype_ddmarker
|
||||
* @copyright 2019 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
||||
require_once($CFG->dirroot . '/question/type/edit_question_form.php');
|
||||
require_once($CFG->dirroot . '/question/type/ddmarker/edit_ddmarker_form.php');
|
||||
|
||||
/**
|
||||
* Unit tests for the drag-and-drop markers edit form.
|
||||
*
|
||||
* @copyright 2019 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_ddmarker_edit_form_test extends advanced_testcase {
|
||||
/**
|
||||
* Helper method.
|
||||
*
|
||||
* @return array with two elements:
|
||||
* question_edit_form great a question form instance that can be tested.
|
||||
* stdClass the question category.
|
||||
*/
|
||||
protected function get_form() {
|
||||
$this->setAdminUser();
|
||||
$this->resetAfterTest();
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$category = question_make_default_categories(array($syscontext));
|
||||
$fakequestion = new stdClass();
|
||||
$fakequestion->qtype = 'ddmarker';
|
||||
$fakequestion->contextid = $syscontext->id;
|
||||
$fakequestion->createdby = 2;
|
||||
$fakequestion->category = $category->id;
|
||||
$fakequestion->questiontext = 'Test question';
|
||||
$fakequestion->options = new stdClass();
|
||||
$fakequestion->options->answers = array();
|
||||
$fakequestion->formoptions = new stdClass();
|
||||
$fakequestion->formoptions->movecontext = null;
|
||||
$fakequestion->formoptions->repeatelements = true;
|
||||
$fakequestion->inputs = null;
|
||||
|
||||
$form = new qtype_ddmarker_edit_form(new moodle_url('/'), $fakequestion, $category,
|
||||
new question_edit_contexts($syscontext));
|
||||
|
||||
return [$form, $category];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the form correctly validates the HTML allowed in items.
|
||||
*/
|
||||
public function test_item_validation() {
|
||||
list($form, $category) = $this->get_form();
|
||||
|
||||
$submitteddata = [
|
||||
'category' => $category->id,
|
||||
'bgimage' => 0,
|
||||
'nodropzone' => 0,
|
||||
'noitems' => 4,
|
||||
'drags' => [
|
||||
['label' => 'frog'],
|
||||
['label' => '<b>toad</b>'],
|
||||
['label' => '<span lang="fr"><em>chien</em></span>'],
|
||||
['label' => '<textarea>evil!</textarea>'],
|
||||
],
|
||||
];
|
||||
|
||||
$errors = $form->validation($submitteddata, []);
|
||||
|
||||
$this->assertArrayNotHasKey('drags[0]', $errors);
|
||||
$this->assertArrayNotHasKey('drags[1]', $errors);
|
||||
$this->assertArrayNotHasKey('drags[2]', $errors);
|
||||
$this->assertEquals('Only "<br><i><em><b><strong>' .
|
||||
'<sup><sub><u><span>" tags are allowed in the label for a marker.',
|
||||
$errors['drags[3]']);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,9 @@ class qtype_ddwtos_edit_form_test extends advanced_testcase {
|
||||
*
|
||||
* @param string $classname the question form class to instantiate.
|
||||
*
|
||||
* @return question_edit_form great a question form instance that can be tested.
|
||||
* @return array with two elements:
|
||||
* question_edit_form great a question form instance that can be tested.
|
||||
* stdClass the question category.
|
||||
*/
|
||||
protected function get_form($classname) {
|
||||
$this->setAdminUser();
|
||||
@@ -50,7 +52,7 @@ class qtype_ddwtos_edit_form_test extends advanced_testcase {
|
||||
$syscontext = context_system::instance();
|
||||
$category = question_make_default_categories(array($syscontext));
|
||||
$fakequestion = new stdClass();
|
||||
$fakequestion->qtype = 'stack';
|
||||
$fakequestion->qtype = 'ddwtos'; // Does not actually matter if this is wrong.
|
||||
$fakequestion->contextid = $syscontext->id;
|
||||
$fakequestion->createdby = 2;
|
||||
$fakequestion->category = $category->id;
|
||||
@@ -61,15 +63,18 @@ class qtype_ddwtos_edit_form_test extends advanced_testcase {
|
||||
$fakequestion->formoptions->movecontext = null;
|
||||
$fakequestion->formoptions->repeatelements = true;
|
||||
$fakequestion->inputs = null;
|
||||
return new $classname(new moodle_url('/'), $fakequestion, $category,
|
||||
|
||||
$form = new $classname(new moodle_url('/'), $fakequestion, $category,
|
||||
new question_edit_contexts($syscontext));
|
||||
|
||||
return [$form, $category];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the form shows the right number of groups of choices.
|
||||
*/
|
||||
public function test_number_of_choice_groups() {
|
||||
$form = $this->get_form('qtype_ddwtos_edit_form');
|
||||
list($form) = $this->get_form('qtype_ddwtos_edit_form');
|
||||
// Use reflection to get the protected property we need.
|
||||
$property = new ReflectionProperty('qtype_ddwtos_edit_form', '_form');
|
||||
$property->setAccessible(true);
|
||||
@@ -78,4 +83,32 @@ class qtype_ddwtos_edit_form_test extends advanced_testcase {
|
||||
$groupoptions = $choices->_elements[1];
|
||||
$this->assertCount(8, $groupoptions->_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the form correctly validates the HTML allowed in choices.
|
||||
*/
|
||||
public function test_choices_validation() {
|
||||
list($form, $category) = $this->get_form('qtype_ddwtos_edit_form');
|
||||
|
||||
$submitteddata = [
|
||||
'category' => $category->id,
|
||||
'questiontext' => ['text' => 'Test [[1]] question [[2]]', 'format' => FORMAT_HTML],
|
||||
'choices' => [
|
||||
['answer' => 'frog'],
|
||||
['answer' => '<b>toad</b>'],
|
||||
['answer' => '<span lang="fr"><em>chien</em></span>'],
|
||||
['answer' => '<textarea>evil!</textarea>'],
|
||||
],
|
||||
];
|
||||
|
||||
$errors = $form->validation($submitteddata, []);
|
||||
|
||||
$this->assertArrayNotHasKey('choices[0]', $errors);
|
||||
$this->assertArrayNotHasKey('choices[1]', $errors);
|
||||
$this->assertArrayNotHasKey('choices[2]', $errors);
|
||||
$this->assertEquals('<textarea> is not allowed. ' .
|
||||
'(Only <sub>, <sup>, <b>, <i>, ' .
|
||||
'<em>, <strong>, <span> are permitted.)',
|
||||
$errors['choices[3]']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@ class qtype_gapselect_edit_form_base extends question_edit_form {
|
||||
'b',
|
||||
'i',
|
||||
'em',
|
||||
'strong'
|
||||
'strong',
|
||||
'span',
|
||||
);
|
||||
|
||||
/** @var string regex to match HTML open tags. */
|
||||
@@ -55,7 +56,7 @@ class qtype_gapselect_edit_form_base extends question_edit_form {
|
||||
/**
|
||||
* Vaidate some input to make sure it does not contain any tags other than
|
||||
* $this->allowedhtmltags.
|
||||
* @param unknown_type $text the input to validate.
|
||||
* @param string $text the input to validate.
|
||||
* @return string any validation errors.
|
||||
*/
|
||||
protected function get_illegal_tag_error($text) {
|
||||
|
||||
@@ -65,7 +65,10 @@ class qtype_gapselect_edit_form_test extends advanced_testcase {
|
||||
*
|
||||
* @param string $classname the question form class to instantiate.
|
||||
*
|
||||
* @return question_edit_form great a question form instance that can be tested.
|
||||
*
|
||||
* @return array with two elements:
|
||||
* question_edit_form great a question form instance that can be tested.
|
||||
* stdClass the question category.
|
||||
*/
|
||||
protected function get_form($classname) {
|
||||
$this->setAdminUser();
|
||||
@@ -74,7 +77,7 @@ class qtype_gapselect_edit_form_test extends advanced_testcase {
|
||||
$syscontext = context_system::instance();
|
||||
$category = question_make_default_categories(array($syscontext));
|
||||
$fakequestion = new stdClass();
|
||||
$fakequestion->qtype = 'stack';
|
||||
$fakequestion->qtype = 'gapselect'; // Does not actually matter if this is wrong.
|
||||
$fakequestion->contextid = $syscontext->id;
|
||||
$fakequestion->createdby = 2;
|
||||
$fakequestion->category = $category->id;
|
||||
@@ -85,19 +88,22 @@ class qtype_gapselect_edit_form_test extends advanced_testcase {
|
||||
$fakequestion->formoptions->movecontext = null;
|
||||
$fakequestion->formoptions->repeatelements = true;
|
||||
$fakequestion->inputs = null;
|
||||
return new $classname(new moodle_url('/'), $fakequestion, $category,
|
||||
|
||||
$form = new $classname(new moodle_url('/'), $fakequestion, $category,
|
||||
new question_edit_contexts($syscontext));
|
||||
|
||||
return [$form, $category];
|
||||
}
|
||||
|
||||
public function test_get_illegal_tag_error() {
|
||||
$form = $this->get_form('qtype_gapselect_edit_form_base_testable');
|
||||
list($form) = $this->get_form('qtype_gapselect_edit_form_base_testable');
|
||||
|
||||
$this->assertEquals('', $form->get_illegal_tag_error('frog'));
|
||||
$this->assertEquals('', $form->get_illegal_tag_error('<i>toad</i>'));
|
||||
|
||||
$a = new stdClass();
|
||||
$a->tag = '<ijk>';
|
||||
$a->allowed = '<sub>, <sup>, <b>, <i>, <em>, <strong>';
|
||||
$a->allowed = '<sub>, <sup>, <b>, <i>, <em>, <strong>, <span>';
|
||||
$this->assertEquals(get_string('tagsnotallowed', 'qtype_gapselect', $a), $form->get_illegal_tag_error('<ijk>'));
|
||||
|
||||
$a->tag = '</cat>';
|
||||
@@ -131,7 +137,7 @@ class qtype_gapselect_edit_form_test extends advanced_testcase {
|
||||
* Test the form shows the right number of groups of choices.
|
||||
*/
|
||||
public function test_number_of_choice_groups() {
|
||||
$form = $this->get_form('qtype_gapselect_edit_form');
|
||||
list($form) = $this->get_form('qtype_gapselect_edit_form');
|
||||
// Use reflection to get the protected property we need.
|
||||
$property = new ReflectionProperty('qtype_gapselect_edit_form', '_form');
|
||||
$property->setAccessible(true);
|
||||
@@ -140,4 +146,26 @@ class qtype_gapselect_edit_form_test extends advanced_testcase {
|
||||
$groupoptions = $choices->_elements[1];
|
||||
$this->assertCount(20, $groupoptions->_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the form correctly validates the HTML allowed in choices.
|
||||
*/
|
||||
public function test_choices_validation() {
|
||||
list($form, $category) = $this->get_form('qtype_gapselect_edit_form');
|
||||
|
||||
$submitteddata = [
|
||||
'category' => $category->id,
|
||||
'questiontext' => ['text' => 'Test [[1]] question [[2]]', 'format' => FORMAT_HTML],
|
||||
'choices' => [
|
||||
['answer' => 'frog'],
|
||||
['answer' => '<b>toad</b>'],
|
||||
],
|
||||
];
|
||||
|
||||
$errors = $form->validation($submitteddata, []);
|
||||
|
||||
$this->assertArrayNotHasKey('choices[0]', $errors);
|
||||
$this->assertEquals('<b> is not allowed. (No HTML is allowed here.)',
|
||||
$errors['choices[1]']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user