From d9b0da85cc1ced503528fd3df2f228151c7e1495 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Mon, 11 Jan 2021 19:59:23 +0000 Subject: [PATCH] MDL-68597 essay word limits: fixes requested by the integrator --- question/type/essay/lang/en/qtype_essay.php | 4 +- question/type/essay/question.php | 6 +- question/type/essay/renderer.php | 2 +- ...ut.feature => edit_min_max_fields.feature} | 0 .../type/essay/tests/behat/preview.feature | 6 +- question/type/essay/tests/question_test.php | 6 +- .../type/essay/tests/walkthrough_test.php | 97 +++++++++++++++++++ 7 files changed, 110 insertions(+), 11 deletions(-) rename question/type/essay/tests/behat/{min_max_text_input.feature => edit_min_max_fields.feature} (100%) diff --git a/question/type/essay/lang/en/qtype_essay.php b/question/type/essay/lang/en/qtype_essay.php index 39cdf85f0e5..e3a84f24834 100644 --- a/question/type/essay/lang/en/qtype_essay.php +++ b/question/type/essay/lang/en/qtype_essay.php @@ -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.'; diff --git a/question/type/essay/question.php b/question/type/essay/question.php index c14af97a8d3..204abaea191 100644 --- a/question/type/essay/question.php +++ b/question/type/essay/question.php @@ -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; diff --git a/question/type/essay/renderer.php b/question/type/essay/renderer.php index 58ba2179a53..0a1e0dedf9c 100644 --- a/question/type/essay/renderer.php +++ b/question/type/essay/renderer.php @@ -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'); diff --git a/question/type/essay/tests/behat/min_max_text_input.feature b/question/type/essay/tests/behat/edit_min_max_fields.feature similarity index 100% rename from question/type/essay/tests/behat/min_max_text_input.feature rename to question/type/essay/tests/behat/edit_min_max_fields.feature diff --git a/question/type/essay/tests/behat/preview.feature b/question/type/essay/tests/behat/preview.feature index 6eb52f327a8..142425c67f5 100644 --- a/question/type/essay/tests/behat/preview.feature +++ b/question/type/essay/tests/behat/preview.feature @@ -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" diff --git a/question/type/essay/tests/question_test.php b/question/type/essay/tests/question_test.php index ab047e17d48..ffd583a525b 100644 --- a/question/type/essay/tests/question_test.php +++ b/question/type/essay/tests/question_test.php @@ -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, ''], ]; } diff --git a/question/type/essay/tests/walkthrough_test.php b/question/type/essay/tests/walkthrough_test.php index 400006a0bfa..1d6c3e1dcda 100644 --- a/question/type/essay/tests/walkthrough_test.php +++ b/question/type/essay/tests/walkthrough_test.php @@ -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 = '
+
+

One

+
+
    +
  • Two
  • +
+
+
+
'; + $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' => '

One two three.

', 'answerformat' => FORMAT_HTML]); + + // Verify. + $this->check_current_state(question_state::$complete); + $this->check_current_mark(null); + $this->render(); + $this->check_contains_textarea('answer', '

One two three.

'); + $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' => '

One two three four five six seven.

', + 'answerformat' => FORMAT_HTML]); + + // Verify. + $this->check_current_state(question_state::$complete); + $this->check_current_mark(null); + $this->render(); + $this->check_contains_textarea('answer', '

One two three four five six seven.

'); + $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' => '

One two three four five six seven eight.

', + 'answerformat' => FORMAT_HTML]); + + // Verify. + $this->check_current_state(question_state::$invalid); + $this->check_current_mark(null); + $this->render(); + $this->check_contains_textarea('answer', '

One two three four five six seven eight.

'); + $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); + + } }