MDL-68597 essay word limits: fixes requested by the integrator
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user