diff --git a/lang/en/attendance.php b/lang/en/attendance.php index c5fabd7..dd7035c 100644 --- a/lang/en/attendance.php +++ b/lang/en/attendance.php @@ -99,6 +99,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['endtime'] = 'Session end time'; $string['endofperiod'] = 'End of period'; $string['enrolmentend'] = 'User enrolment ends {$a}'; diff --git a/locallib.php b/locallib.php index 8df8c25..4ddf321 100644 --- a/locallib.php +++ b/locallib.php @@ -1487,6 +1487,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 ce30721..062c547 100644 --- a/preferences.php +++ b/preferences.php @@ -48,6 +48,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); @@ -98,7 +100,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); @@ -108,7 +110,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)); // Output starts here. diff --git a/renderables.php b/renderables.php index 924dda9..61997a6 100644 --- a/renderables.php +++ b/renderables.php @@ -535,8 +535,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 3645fd4..7138e15 100644 --- a/renderer.php +++ b/renderer.php @@ -926,9 +926,22 @@ 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('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); @@ -1003,4 +1016,16 @@ 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); + } + } 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"