From 7fd4b431b179b12972851821f1c2ac09613a796d Mon Sep 17 00:00:00 2001 From: Barry Oosthuizen Date: Wed, 22 Jul 2015 11:57:46 +0100 Subject: [PATCH 1/2] Fix issue#129 - Notify error for empty acronym or description --- lang/en/attendance.php | 4 +++- locallib.php | 4 ++++ preferences.php | 6 ++++-- renderables.php | 5 ++++- renderer.php | 29 ++++++++++++++++++++++++++--- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lang/en/attendance.php b/lang/en/attendance.php index 2a16291..cfc32d1 100644 --- a/lang/en/attendance.php +++ b/lang/en/attendance.php @@ -103,6 +103,8 @@ $string['downloadtext'] = 'Download in text format'; $string['donotusepaging'] = 'Do not use paging'; $string['duration'] = 'Duration'; $string['editsession'] = 'Edit Session'; +$string['emptyacronym'] = 'Empty acronyms are not allowed. Status record not updated.'; +$string['emptydescription'] = 'Empty descriptions are not allowed. Status record not updated.'; $string['edituser'] = 'Edit user'; $string['endtime'] = 'Session end time'; $string['endofperiod'] = 'End of period'; @@ -297,4 +299,4 @@ $string['attendance_already_submitted'] = 'You may not self register attendance $string['lowgrade'] = 'Low grade'; $string['submitattendance'] = 'Submit attendance'; $string['attendancenotset'] = 'You must set your attendance'; -$string['export'] = 'Export'; \ No newline at end of file +$string['export'] = 'Export'; diff --git a/locallib.php b/locallib.php index 122159b..e6808c3 100644 --- a/locallib.php +++ b/locallib.php @@ -1596,6 +1596,10 @@ class attendance { public function update_status($status, $acronym, $description, $grade, $visible) { global $DB; + if (empty($acronym) || empty($description)) { + return array('acronym' => $acronym, 'description' => $description); + } + $updated = array(); if ($acronym) { diff --git a/preferences.php b/preferences.php index 57b53ea..876f595 100644 --- a/preferences.php +++ b/preferences.php @@ -55,6 +55,8 @@ $PAGE->set_cacheable(true); $PAGE->set_button($OUTPUT->update_module_button($cm->id, 'attendance')); $PAGE->navbar->add(get_string('settings', 'attendance')); +$errors = array(); + switch ($att->pageparams->action) { case att_preferences_page_params::ACTION_ADD: $newacronym = optional_param('newacronym', null, PARAM_TEXT); @@ -112,7 +114,7 @@ switch ($att->pageparams->action) { foreach ($acronym as $id => $v) { $status = $statuses[$id]; - $att->update_status($status, $acronym[$id], $description[$id], $grade[$id], null); + $errors[$id] = $att->update_status($status, $acronym[$id], $description[$id], $grade[$id], null); } if ($att->grade > 0) { att_update_all_users_grades($att->id, $att->course, $att->context, $cm); @@ -122,7 +124,7 @@ switch ($att->pageparams->action) { $output = $PAGE->get_renderer('mod_attendance'); $tabs = new attendance_tabs($att, attendance_tabs::TAB_PREFERENCES); -$prefdata = new attendance_preferences_data($att); +$prefdata = new attendance_preferences_data($att, array_filter($errors)); $setselector = new attendance_set_selector($att, $maxstatusset); // Output starts here. diff --git a/renderables.php b/renderables.php index 8b04082..d6fef01 100644 --- a/renderables.php +++ b/renderables.php @@ -548,8 +548,11 @@ class attendance_preferences_data implements renderable { private $att; - public function __construct(attendance $att) { + public $errors; + + public function __construct(attendance $att, $errors) { $this->statuses = $att->get_statuses(false); + $this->errors = $errors; foreach ($this->statuses as $st) { $st->haslogs = att_has_logs_for_status ($st->id); diff --git a/renderer.php b/renderer.php index 3aea268..f404a2c 100644 --- a/renderer.php +++ b/renderer.php @@ -963,10 +963,21 @@ class mod_attendance_renderer extends plugin_renderer_base { $i = 1; foreach ($prefdata->statuses as $st) { + $emptyacronym = ''; + $emptydescription = ''; + if (array_key_exists($st->id, $prefdata->errors)) { + if (empty($prefdata->errors[$st->id]['acronym'])) { + $emptyacronym = $this->construct_notice(get_string('emptyacronym', 'mod_attendance'), 'notifyproblem'); + } + if (empty($prefdata->errors[$st->id]['description'])) { + $emptydescription = $this->construct_notice(get_string('emptydescription', 'mod_attendance') , 'notifyproblem'); + } + } + $table->data[$i][] = $i; - $table->data[$i][] = $this->construct_text_input('acronym['.$st->id.']', 2, 2, $st->acronym); - $table->data[$i][] = $this->construct_text_input('description['.$st->id.']', 30, 30, $st->description); - $table->data[$i][] = $this->construct_text_input('grade['.$st->id.']', 4, 4, format_float($st->grade)); + $table->data[$i][] = $this->construct_text_input('acronym['.$st->id.']', 2, 2, $st->acronym) . $emptyacronym; + $table->data[$i][] = $this->construct_text_input('description['.$st->id.']', 30, 30, $st->description) . $emptydescription; + $table->data[$i][] = $this->construct_text_input('grade['.$st->id.']', 4, 4, $st->grade); $table->data[$i][] = $this->construct_preferences_actions_icons($st, $prefdata); $i++; @@ -1040,6 +1051,18 @@ class mod_attendance_renderer extends plugin_renderer_base { return html_writer::empty_tag('input', $attributes); } + /** + * Construct a notice message + * + * @param string $text + * @param string $class + * @return string + */ + private function construct_notice($text, $class = 'notifymessage') { + $attributes = array('class' => $class); + return html_writer::tag('p', $text, $attributes); + } + // Show different picture if it is a temporary user. protected function user_picture($user, array $opts = null) { if ($user->type == 'temporary') { From 7d39e1b2f1714aba4a6483cbb79805dbc890a3c2 Mon Sep 17 00:00:00 2001 From: Barry Oosthuizen Date: Wed, 22 Jul 2015 11:58:07 +0100 Subject: [PATCH 2/2] Behat test to notify error for empty acronym or description --- tests/behat/preferences.feature | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/behat/preferences.feature diff --git a/tests/behat/preferences.feature b/tests/behat/preferences.feature new file mode 100644 index 0000000..0f30cbb --- /dev/null +++ b/tests/behat/preferences.feature @@ -0,0 +1,55 @@ +@mod @uon @mod_attendance @mod_attendance_preferences +Feature: Teachers can't change status variables to have empty acronyms or descriptions + In order to update status variables + As a teacher + I need to see an error notice below each acronym / description that I try to set to be empty + + Background: + Given the following "courses" exist: + | fullname | shortname | summary | category | + | Course 1 | C101 | Prove the attendance activity settings works | 0 | + And the following "users" exist: + | username | firstname | lastname | + | student1 | Sam | Student | + | teacher1 | Teacher | One | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C101 | student | + | teacher1 | C101 | editingteacher | + And I log in as "teacher1" + And I follow "Course 1" + And I turn editing mode on + And I add a "Attendance" to section "1" + And I press "Save and display" + And I follow "Settings" + + @javascript + Scenario: Teachers can add status variables + # Set the second status acronym to be empty + Given I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[2]/td[2]/input" to "" + # Set the second status description to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[2]/td[3]/input" to "" + # Set the second status grade to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[2]/td[4]/input" to "" + When I click on "Update" "button" in the "#preferencesform" "css_element" + Then I should see "Empty acronyms are not allowed" in the "//*[@id='preferencesform']/table/tbody/tr[2]/td[2]/p" "xpath_element" + And I should see "Empty descriptions are not allowed" in the "//*[@id='preferencesform']/table/tbody/tr[2]/td[3]/p" "xpath_element" + And I click on "Update" "button" in the "#preferencesform" "css_element" + + # Set the first status acronym to be empty + Given I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[1]/td[2]/input" to "" + # Set the first status description to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[1]/td[3]/input" to "" + # Set the first status grade to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[1]/td[4]/input" to "" + # Set the third status acronym to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[3]/td[2]/input" to "" + # Set the third status description to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[3]/td[3]/input" to "" + # Set the third status grade to be empty + And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[3]/td[4]/input" to "" + When I click on "Update" "button" in the "#preferencesform" "css_element" + Then I should see "Empty acronyms are not allowed" in the "//*[@id='preferencesform']/table/tbody/tr[1]/td[2]/p" "xpath_element" + And I should see "Empty descriptions are not allowed" in the "//*[@id='preferencesform']/table/tbody/tr[1]/td[3]/p" "xpath_element" + And I should see "Empty acronyms are not allowed" in the "//*[@id='preferencesform']/table/tbody/tr[3]/td[2]/p" "xpath_element" + And I should see "Empty descriptions are not allowed" in the "//*[@id='preferencesform']/table/tbody/tr[3]/td[3]/p" "xpath_element"