mirror of
https://github.com/moodle/moodle.git
synced 2025-08-06 09:26:35 +02:00
MDL-39980 question engine: Attempt on last loses response files
When doing Each attempt builds on last, we need to copy any response files into a draft file area, and then re-save them. While writing the unit test for this, I had to deal with a todo in the question engine so that questions with files in the response could be unit-tested. I also found an fixed a bug with qtype_essay_question::is_same_response and fixed some notices in the existing essay/manual graded unit tests.
This commit is contained in:
parent
838d78a9ff
commit
afb1b3d03b
8 changed files with 221 additions and 18 deletions
|
@ -87,12 +87,12 @@ class qtype_essay_question extends question_with_responses {
|
|||
|
||||
public function is_same_response(array $prevresponse, array $newresponse) {
|
||||
if (array_key_exists('answer', $prevresponse) && $prevresponse['answer'] !== $this->responsetemplate) {
|
||||
$value1 = $prevresponse['answer'];
|
||||
$value1 = (string) $prevresponse['answer'];
|
||||
} else {
|
||||
$value1 = '';
|
||||
}
|
||||
if (array_key_exists('answer', $newresponse) && $newresponse['answer'] !== $this->responsetemplate) {
|
||||
$value2 = $newresponse['answer'];
|
||||
$value2 = (string) $newresponse['answer'];
|
||||
} else {
|
||||
$value2 = '';
|
||||
}
|
||||
|
|
|
@ -78,6 +78,29 @@ class qtype_essay_test_helper extends question_test_helper {
|
|||
return $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the data what would be received from the editing form for an essay
|
||||
* question using the HTML editor allowing embedded files as input, and up
|
||||
* to three attachments.
|
||||
*
|
||||
* @return stdClass the data that would be returned by $form->get_gata();
|
||||
*/
|
||||
public function get_essay_question_form_data_editorfilepicker() {
|
||||
$fromform = new stdClass();
|
||||
|
||||
$fromform->name = 'Essay question with filepicker and attachments';
|
||||
$fromform->questiontext = array('text' => 'Please write a story about a frog.', 'format' => FORMAT_HTML);
|
||||
$fromform->defaultmark = 1.0;
|
||||
$fromform->generalfeedback = array('text' => 'I hope your story had a beginning, a middle and an end.', 'format' => FORMAT_HTML);
|
||||
$fromform->responseformat = 'editorfilepicker';
|
||||
$fromform->responsefieldlines = 10;
|
||||
$fromform->attachments = 3;
|
||||
$fromform->graderinfo = array('text' => '', 'format' => FORMAT_HTML);
|
||||
$fromform->responsetemplate = array('text' => '', 'format' => FORMAT_HTML);
|
||||
|
||||
return $fromform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an essay question using plain text input.
|
||||
* @return qtype_essay_question
|
||||
|
|
|
@ -36,7 +36,7 @@ require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
|||
* @copyright 2009 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_essay_question_test extends advanced_testcase {
|
||||
class qtype_essay_question_testcase extends advanced_testcase {
|
||||
public function test_get_question_summary() {
|
||||
$essay = test_question_maker::make_an_essay_question();
|
||||
$essay->questiontext = 'Hello <img src="http://example.com/globe.png" alt="world" />';
|
||||
|
@ -46,8 +46,8 @@ class qtype_essay_question_test extends advanced_testcase {
|
|||
public function test_summarise_response() {
|
||||
$longstring = str_repeat('0123456789', 50);
|
||||
$essay = test_question_maker::make_an_essay_question();
|
||||
$this->assertEquals($longstring,
|
||||
$essay->summarise_response(array('answer' => $longstring, 'answerformat' => FORMAT_PLAIN)));
|
||||
$this->assertEquals($longstring, $essay->summarise_response(
|
||||
array('answer' => $longstring, 'answerformat' => FORMAT_HTML)));
|
||||
}
|
||||
|
||||
public function test_is_same_response() {
|
||||
|
|
|
@ -35,7 +35,7 @@ require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
|||
* @copyright 2013 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_essay_walkthrough_test extends qbehaviour_walkthrough_test_base {
|
||||
class qtype_essay_walkthrough_testcase extends qbehaviour_walkthrough_test_base {
|
||||
|
||||
protected function check_contains_textarea($name, $content = '', $height = 10) {
|
||||
$fieldname = $this->quba->get_field_prefix($this->slot) . $name;
|
||||
|
@ -50,6 +50,28 @@ class qtype_essay_walkthrough_test extends qbehaviour_walkthrough_test_base {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method: Store a test file with a given name and contents in a
|
||||
* draft file area.
|
||||
*
|
||||
* @param int $usercontextid user context id.
|
||||
* @param int $draftitemid draft item id.
|
||||
* @param string $filename filename.
|
||||
* @param string $contents file contents.
|
||||
*/
|
||||
protected function save_file_to_draft_area($usercontextid, $draftitemid, $filename, $contents) {
|
||||
$fs = get_file_storage();
|
||||
|
||||
$filerecord = new stdClass();
|
||||
$filerecord->contextid = $usercontextid;
|
||||
$filerecord->component = 'user';
|
||||
$filerecord->filearea = 'draft';
|
||||
$filerecord->itemid = $draftitemid;
|
||||
$filerecord->filepath = '/';
|
||||
$filerecord->filename = $filename;
|
||||
$fs->create_file_from_string($filerecord, $contents);
|
||||
}
|
||||
|
||||
public function test_deferred_feedback_html_editor() {
|
||||
|
||||
// Create an essay question.
|
||||
|
@ -204,4 +226,126 @@ class qtype_essay_walkthrough_test extends qbehaviour_walkthrough_test_base {
|
|||
$this->get_contains_question_text_expectation($q),
|
||||
$this->get_contains_general_feedback_expectation($q));
|
||||
}
|
||||
|
||||
public function test_deferred_feedback_html_editor_with_files_attempt_on_last() {
|
||||
global $CFG, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
$usercontextid = context_user::instance($USER->id)->id;
|
||||
$fs = get_file_storage();
|
||||
|
||||
// Create an essay question in the DB.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
$cat = $generator->create_question_category();
|
||||
$question = $generator->create_question('essay', 'editorfilepicker', array('category' => $cat->id));
|
||||
|
||||
// Start attempt at the question.
|
||||
$q = question_bank::load_question($question->id);
|
||||
$this->start_attempt_at_question($q, 'deferredfeedback', 1);
|
||||
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_step_count(1);
|
||||
|
||||
// Process a response and check the expected result.
|
||||
// First we need to get the draft item ids.
|
||||
$this->render();
|
||||
if (!preg_match('/env=editor&.*?itemid=(\d+)&/', $this->currentoutput, $matches)) {
|
||||
throw new coding_exception('Editor draft item id not found.');
|
||||
}
|
||||
$editordraftid = $matches[1];
|
||||
if (!preg_match('/env=filemanager&action=browse&.*?itemid=(\d+)&/', $this->currentoutput, $matches)) {
|
||||
throw new coding_exception('File manager draft item id not found.');
|
||||
}
|
||||
$attachementsdraftid = $matches[1];
|
||||
|
||||
$this->save_file_to_draft_area($usercontextid, $editordraftid, 'smile.txt', ':-)');
|
||||
$this->save_file_to_draft_area($usercontextid, $attachementsdraftid, 'greeting.txt', 'Hello world!');
|
||||
$this->process_submission(array(
|
||||
'answer' => 'Here is a picture: <img src="' . $CFG->wwwroot .
|
||||
"/draftfile.php/{$usercontextid}/user/draft/{$editordraftid}/smile.txt" .
|
||||
'" alt="smile">.',
|
||||
'answerformat' => FORMAT_HTML,
|
||||
'answer:itemid' => $editordraftid,
|
||||
'attachments' => $attachementsdraftid));
|
||||
|
||||
$this->check_current_state(question_state::$complete);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_step_count(2);
|
||||
$this->save_quba();
|
||||
|
||||
// Save the same response again, and verify no new step is created.
|
||||
$this->load_quba();
|
||||
|
||||
$this->render();
|
||||
if (!preg_match('/env=editor&.*?itemid=(\d+)&/', $this->currentoutput, $matches)) {
|
||||
throw new coding_exception('Editor draft item id not found.');
|
||||
}
|
||||
$editordraftid = $matches[1];
|
||||
if (!preg_match('/env=filemanager&action=browse&.*?itemid=(\d+)&/', $this->currentoutput, $matches)) {
|
||||
throw new coding_exception('File manager draft item id not found.');
|
||||
}
|
||||
$attachementsdraftid = $matches[1];
|
||||
|
||||
$this->process_submission(array(
|
||||
'answer' => 'Here is a picture: <img src="' . $CFG->wwwroot .
|
||||
"/draftfile.php/{$usercontextid}/user/draft/{$editordraftid}/smile.txt" .
|
||||
'" alt="smile">.',
|
||||
'answerformat' => FORMAT_HTML,
|
||||
'answer:itemid' => $editordraftid,
|
||||
'attachments' => $attachementsdraftid));
|
||||
|
||||
$this->check_current_state(question_state::$complete);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_step_count(2);
|
||||
|
||||
// Now submit all and finish.
|
||||
$this->finish();
|
||||
$this->check_current_state(question_state::$needsgrading);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_step_count(3);
|
||||
$this->save_quba();
|
||||
|
||||
// Now start a new attempt based on the old one.
|
||||
$this->load_quba();
|
||||
$oldqa = $this->get_question_attempt();
|
||||
|
||||
$q = question_bank::load_question($question->id);
|
||||
$this->quba = question_engine::make_questions_usage_by_activity('unit_test',
|
||||
context_system::instance());
|
||||
$this->quba->set_preferred_behaviour('deferredfeedback');
|
||||
$this->slot = $this->quba->add_question($q, 1);
|
||||
$this->quba->start_question_based_on($this->slot, $oldqa);
|
||||
|
||||
$this->check_current_state(question_state::$complete);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_step_count(1);
|
||||
$this->save_quba();
|
||||
|
||||
// Now save the same response again, and ensure that a new step is not created.
|
||||
$this->load_quba();
|
||||
|
||||
$this->render();
|
||||
if (!preg_match('/env=editor&.*?itemid=(\d+)&/', $this->currentoutput, $matches)) {
|
||||
throw new coding_exception('Editor draft item id not found.');
|
||||
}
|
||||
$editordraftid = $matches[1];
|
||||
if (!preg_match('/env=filemanager&action=browse&.*?itemid=(\d+)&/', $this->currentoutput, $matches)) {
|
||||
throw new coding_exception('File manager draft item id not found.');
|
||||
}
|
||||
$attachementsdraftid = $matches[1];
|
||||
|
||||
$this->process_submission(array(
|
||||
'answer' => 'Here is a picture: <img src="' . $CFG->wwwroot .
|
||||
"/draftfile.php/{$usercontextid}/user/draft/{$editordraftid}/smile.txt" .
|
||||
'" alt="smile">.',
|
||||
'answerformat' => FORMAT_HTML,
|
||||
'answer:itemid' => $editordraftid,
|
||||
'attachments' => $attachementsdraftid));
|
||||
|
||||
$this->check_current_state(question_state::$complete);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_step_count(1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue