Commit d9b0da85 authored by Tim Hunt's avatar Tim Hunt

MDL-68597 essay word limits: fixes requested by the integrator

parent 997a407b
......@@ -44,10 +44,10 @@ $string['graderinfoheader'] = 'Grader Information';
$string['maxbytes'] = 'Maximum file size';
$string['maxwordlimit'] = 'Maximum word limit';
$string['maxwordlimit_help'] = 'If the response requires that students enter text, this is the maximum number of words that each student will be allowed to submit.';
$string['maxwordlimitboundary'] = 'The required maximum word limit ({$a} words) has been exceeded for this essay. Please amend your response and try again.';
$string['maxwordlimitboundary'] = 'The word limit for this question is {$a->limit} words and you are attempting to submit {$a->count} words. Please shorten your response and try again.';
$string['minwordlimit'] = 'Minimum word limit';
$string['minwordlimit_help'] = 'If the response requires that students enter text, this is the minimum number of words that each student will be allowed to submit.';
$string['minwordlimitboundary'] = 'The required minimum word limit ({$a} words) has not been reached for this essay. Please amend your response and try again.';
$string['minwordlimitboundary'] = 'This question requires a response of at least {$a->limit} words and you are attempting to submit {$a->count} words. Please expand your response and try again.';
$string['mustattach'] = 'When "No online text" is selected, or responses are optional, you must allow at least one attachment.';
$string['mustrequire'] = 'When "No online text" is selected, or responses are optional, you must require at least one attachment.';
$string['mustrequirefewer'] = 'You cannot require more attachments than you allow.';
......
......@@ -257,10 +257,12 @@ class qtype_essay_question extends question_with_responses {
// Count the number of words in the response string.
$responsewords = count_words($responsestring);
if (isset($this->minwordlimit) && $this->minwordlimit > $responsewords) {
return get_string('minwordlimitboundary', 'qtype_essay', $this->minwordlimit);
return get_string('minwordlimitboundary', 'qtype_essay',
['limit' => $this->minwordlimit, 'count' => $responsewords]);
}
if (isset($this->maxwordlimit) && $this->maxwordlimit < $responsewords) {
return get_string('maxwordlimitboundary', 'qtype_essay', $this->maxwordlimit);
return get_string('maxwordlimitboundary', 'qtype_essay',
['limit' => $this->maxwordlimit, 'count' => $responsewords]);
}
}
return null;
......
......@@ -77,7 +77,7 @@ class qtype_essay_renderer extends qtype_renderer {
// If there is a response and min/max word limit is set in the form then check the response word count.
if ($qa->get_state() == question_state::$invalid) {
$result .= html_writer::nonempty_tag('div',
$question->get_validation_error(['answer' => $answer]), ['class' => 'validationerror']);
$question->get_validation_error($step->get_qt_data()), ['class' => 'validationerror']);
}
$result .= html_writer::tag('div', $files, array('class' => 'attachments'));
$result .= html_writer::end_tag('div');
......
......@@ -27,7 +27,7 @@ Feature: Preview Essay questions
And I navigate to "Question bank" in current page administration
@javascript @_switch_window
Scenario: Preview an Essay question and submit a partially correct response.
Scenario: Preview an Essay question that uses the HTML editor.
When I choose "Preview" action for "essay-001" in the question bank
And I switch to "questionpreview" window
And I set the field "How questions behave" to "Immediate feedback"
......@@ -36,7 +36,7 @@ Feature: Preview Essay questions
And I switch to the main window
@javascript @_switch_window
Scenario: Preview an Essay question and submit a partially correct response.
Scenario: Preview an Essay question that uses the HTML editor with embedded files.
When I choose "Preview" action for "essay-002" in the question bank
And I switch to "questionpreview" window
And I set the field "How questions behave" to "Immediate feedback"
......@@ -46,7 +46,7 @@ Feature: Preview Essay questions
And I switch to the main window
@javascript @_switch_window
Scenario: Preview an Essay question and submit a partially correct response.
Scenario: Preview an Essay question that uses a plain text area.
When I choose "Preview" action for "essay-003" in the question bank
And I switch to "questionpreview" window
And I set the field "How questions behave" to "Immediate feedback"
......
......@@ -308,10 +308,10 @@ class qtype_essay_question_test extends advanced_testcase {
return [
'text input required, min/max word limit not set' => [1, 0, 0, ''],
'text input required, min/max word limit valid (within the boundaries)' => [1, 10, 25, ''],
'text input required, max word limit not reached' => [1, 15, 25,
get_string('minwordlimitboundary', 'qtype_essay', 15)],
'text input required, min word limit not reached' => [1, 15, 25,
get_string('minwordlimitboundary', 'qtype_essay', ['count' => 14, 'limit' => 15])],
'text input required, max word limit is exceeded' => [1, 5, 12,
get_string('maxwordlimitboundary', 'qtype_essay', 12)],
get_string('maxwordlimitboundary', 'qtype_essay', ['count' => 14, 'limit' => 12])],
'text input not required, min/max word limit not set' => [0, 5, 12, ''],
];
}
......
......@@ -619,4 +619,101 @@ class qtype_essay_walkthrough_testcase extends qbehaviour_walkthrough_test_base
$this->check_step_count(3);
$this->save_quba();
}
public function test_deferred_feedback_word_limits() {
global $PAGE;
// The current text editor depends on the users profile setting - so it needs a valid user.
$this->setAdminUser();
// Required to init a text editor.
$PAGE->set_url('/');
// Create an essay question.
/** @var qtype_essay_question $q */
$q = test_question_maker::make_question('essay', 'editor');
$q->minwordlimit = 3;
$q->maxwordlimit = 7;
$this->start_attempt_at_question($q, 'deferredfeedback', 1);
// Check the initial state.
$this->check_current_state(question_state::$todo);
$this->check_current_mark(null);
$this->render();
$this->check_contains_textarea('answer', '');
$this->check_current_output(
$this->get_contains_question_text_expectation($q),
$this->get_does_not_contain_validation_error_expectation(),
$this->get_does_not_contain_feedback_expectation());
// Save a response that is too short (and give the word-count code a tricky case).
$response = '<div class="card">
<div class="card-body">
<h3 class="card-title">One</h3>
<div class="card-text">
<ul>
<li>Two</li>
</ul>
</div>
</div>
</div>';
$this->process_submission(['answer' => $response, 'answerformat' => FORMAT_HTML]);
// Verify.
$this->check_current_state(question_state::$invalid);
$this->check_current_mark(null);
$this->render();
$this->check_contains_textarea('answer', $response);
$this->check_current_output(
$this->get_contains_question_text_expectation($q),
$this->get_contains_validation_error_expectation(),
$this->get_does_not_contain_feedback_expectation());
$this->assertStringContainsString('This question requires a response of at least 3 words and you are ' .
'attempting to submit 2 words. Please expand your response and try again.',
$this->currentoutput);
// Save a response that is just long enough.
$this->process_submission(['answer' => '<p>One two three.</p>', 'answerformat' => FORMAT_HTML]);
// Verify.
$this->check_current_state(question_state::$complete);
$this->check_current_mark(null);
$this->render();
$this->check_contains_textarea('answer', '<p>One two three.</p>');
$this->check_current_output(
$this->get_contains_question_text_expectation($q),
$this->get_does_not_contain_validation_error_expectation(),
$this->get_does_not_contain_feedback_expectation());
// Save a response that is as long as possible short.
$this->process_submission(['answer' => '<p>One two three four five six seven.</p>',
'answerformat' => FORMAT_HTML]);
// Verify.
$this->check_current_state(question_state::$complete);
$this->check_current_mark(null);
$this->render();
$this->check_contains_textarea('answer', '<p>One two three four five six seven.</p>');
$this->check_current_output(
$this->get_contains_question_text_expectation($q),
$this->get_does_not_contain_validation_error_expectation(),
$this->get_does_not_contain_feedback_expectation());
// Save a response that is just too long.
$this->process_submission(['answer' => '<p>One two three four five six seven eight.</p>',
'answerformat' => FORMAT_HTML]);
// Verify.
$this->check_current_state(question_state::$invalid);
$this->check_current_mark(null);
$this->render();
$this->check_contains_textarea('answer', '<p>One two three four five six seven eight.</p>');
$this->check_current_output(
$this->get_contains_question_text_expectation($q),
$this->get_contains_validation_error_expectation(),
$this->get_does_not_contain_feedback_expectation());
$this->assertStringContainsString('The word limit for this question is 7 words and you are ' .
'attempting to submit 8 words. Please shorten your response and try again.',
$this->currentoutput);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment