From d6cea5ccd901265e7b09f01b8789f91b83d57c63 Mon Sep 17 00:00:00 2001 From: Alexander Bias Date: Wed, 27 Mar 2019 21:18:42 +0100 Subject: [PATCH] MDL-65056 completion: Hide checkboxes on course page for teachers --- completion/tests/behat/behat_completion.php | 68 +++++++++++++++++++ .../completion_course_page_checkboxes.feature | 65 ++++++++++++++++++ completion/upgrade.txt | 4 ++ course/renderer.php | 61 +++++++++-------- lib/completionlib.php | 5 +- 5 files changed, 174 insertions(+), 29 deletions(-) create mode 100644 completion/tests/behat/completion_course_page_checkboxes.feature diff --git a/completion/tests/behat/behat_completion.php b/completion/tests/behat/behat_completion.php index 296f92e4ae3..39569593cba 100644 --- a/completion/tests/behat/behat_completion.php +++ b/completion/tests/behat/behat_completion.php @@ -152,4 +152,72 @@ class behat_completion extends behat_base { array($imgalttext, "icon", $activityxpath, "xpath_element") ); } + + /** + * Checks if the activity with specified name shows a information completion checkbox (i.e. showing the completion tracking + * configuration). + * + * @Given /^the "(?P(?:[^"]|\\")*)" "(?P(?:[^"]|\\")*)" activity with "(manual|auto)" completion shows a configuration completion checkbox/ + * @param string $activityname The activity name. + * @param string $activitytype The activity type. + * @param string $completiontype The completion type. + */ + public function activity_has_configuration_completion_checkbox($activityname, $activitytype, $completiontype) { + if ($completiontype == "manual") { + $imgname = 'i/completion-manual-enabled'; + } else { + $imgname = 'i/completion-auto-enabled'; + } + $iconxpath = "//li[contains(concat(' ', @class, ' '), ' modtype_" . strtolower($activitytype) . " ')]"; + $iconxpath .= "[descendant::*[contains(text(), '" . $activityname . "')]]"; + $iconxpath .= "/descendant::span[@class='actions']/descendant::img[contains(@src, 'i/completion-')]"; + + $this->execute("behat_general::the_attribute_of_should_contain", + array("src", $iconxpath, "xpath_element", $imgname) + ); + } + + /** + * Checks if the activity with specified name shows a tracking completion checkbox (i.e. showing my completion tracking status) + * + * @Given /^the "(?P(?:[^"]|\\")*)" "(?P(?:[^"]|\\")*)" activity with "(manual|auto)" completion shows a status completion checkbox/ + * @param string $activityname The activity name. + * @param string $activitytype The activity type. + * @param string $completiontype The completion type. + */ + public function activity_has_status_completion_checkbox($activityname, $activitytype, $completiontype) { + if ($completiontype == "manual") { + $imgname = 'i/completion-manual-'; + } else { + $imgname = 'i/completion-auto-'; + } + $iconxpath = "//li[contains(concat(' ', @class, ' '), ' modtype_" . strtolower($activitytype) . " ')]"; + $iconxpath .= "[descendant::*[contains(text(), '" . $activityname . "')]]"; + $iconxpath .= "/descendant::span[@class='actions']/descendant::img[contains(@src, 'i/completion-')]"; + + $this->execute("behat_general::the_attribute_of_should_contain", + array("src", $iconxpath, "xpath_element", $imgname) + ); + + $this->execute("behat_general::the_attribute_of_should_not_contain", + array("src", $iconxpath, "xpath_element", '-enabled') + ); + } + + /** + * Checks if the activity with specified name does not show any completion checkbox. + * + * @Given /^the "(?P(?:[^"]|\\")*)" "(?P(?:[^"]|\\")*)" activity does not show any completion checkbox/ + * @param string $activityname The activity name. + * @param string $activitytype The activity type. + */ + public function activity_has_not_any_completion_checkbox($activityname, $activitytype) { + $iconxpath = "//li[contains(concat(' ', @class, ' '), ' modtype_" . strtolower($activitytype) . " ')]"; + $iconxpath .= "[descendant::*[contains(text(), '" . $activityname . "')]]"; + $iconxpath .= "/descendant::img[contains(@src, 'i/completion-')]"; + + $this->execute("behat_general::should_not_exist", + array($iconxpath, "xpath_element") + ); + } } diff --git a/completion/tests/behat/completion_course_page_checkboxes.feature b/completion/tests/behat/completion_course_page_checkboxes.feature new file mode 100644 index 00000000000..48005eee0c6 --- /dev/null +++ b/completion/tests/behat/completion_course_page_checkboxes.feature @@ -0,0 +1,65 @@ +@core @core_completion +Feature: Show activity completion status or activity completion configuration on the course page + In order to understand the configuration or status of an activity's completion + As a user + I want to see an appropriate checkbox icon besides the activity + + Background: + Given the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | First | teacher1@example.com | + | teacher2 | Teacher | Second | teacher2@example.com | + | student1 | Student | First | student1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | teacher2 | C1 | teacher | + | student1 | C1 | student | + And I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | Enable completion tracking | Yes | + And I press "Save and display" + And the following "activities" exist: + | activity | course | idnumber | name | intro | completion | completionview | completionexpected | + | forum | C1 | forum1 | Test forum name | Test forum description | 1 | 0 | 0 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | completion | completionview | completionexpected | + | assign | C1 | assign1 | Test assignment name | Test assignment description | 2 | 1 | 0 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | completion | completionview | completionexpected | + | quiz | C1 | quiz1 | Test quiz name | Test quiz description | 0 | 0 | 0 | + And I log out + + Scenario: Show completion status to students + Given I log in as "student1" + And I am on "Course 1" course homepage + Then I should see "Your progress" + And the "Test forum name" "Forum" activity with "manual" completion shows a status completion checkbox + And the "Test assignment name" "Assign" activity with "auto" completion shows a status completion checkbox + And the "Test quiz name" "Quiz" activity does not show any completion checkbox + + Scenario: Show completion configuration to editing teachers + Given I log in as "teacher1" + And I am on "Course 1" course homepage + Then I should not see "Your progress" + And the "Test forum name" "Forum" activity with "manual" completion shows a configuration completion checkbox + And the "Test assignment name" "Assign" activity with "auto" completion shows a configuration completion checkbox + And the "Test quiz name" "Quiz" activity does not show any completion checkbox + And I am on "Course 1" course homepage with editing mode on + And I should not see "Your progress" + And the "Test forum name" "Forum" activity with "manual" completion shows a configuration completion checkbox + And the "Test assignment name" "Assign" activity with "auto" completion shows a configuration completion checkbox + And the "Test quiz name" "Quiz" activity does not show any completion checkbox + + Scenario: Show completion configuration to non-editing teachers + Given I log in as "teacher2" + And I am on "Course 1" course homepage + Then I should not see "Your progress" + And the "Test forum name" "Forum" activity with "manual" completion shows a configuration completion checkbox + And the "Test assignment name" "Assign" activity with "auto" completion shows a configuration completion checkbox + And the "Test quiz name" "Quiz" activity does not show any completion checkbox diff --git a/completion/upgrade.txt b/completion/upgrade.txt index db2324daf7a..dc0dbed677f 100644 --- a/completion/upgrade.txt +++ b/completion/upgrade.txt @@ -4,6 +4,10 @@ information provided here is intended especially for developers. === 3.7 === * External function core_completion_external::get_activities_completion_status new returns the following additional field: - valueused (indicates whether the completion state affects the availability of other content) + * On the course page, only users with the capability 'moodle/course:isincompletionreports' (students, by default) can now tick the + completion checkboxes. Teachers no longer get working checkboxes; tey see slightly different icons that indicate whether + completion is enabled for the activity. These are the same icons which have always been shown to teachers before when the + enabled the course editing mode. === 2.9 === diff --git a/course/renderer.php b/course/renderer.php index 55f5ebed0b7..9d1439c7ad8 100644 --- a/course/renderer.php +++ b/course/renderer.php @@ -403,8 +403,12 @@ class core_course_renderer extends plugin_renderer_base { * @return string */ public function course_section_cm_completion($course, &$completioninfo, cm_info $mod, $displayoptions = array()) { - global $CFG, $DB; + global $CFG, $DB, $USER; $output = ''; + + $istrackeduser = $completioninfo->is_tracked_user($USER->id); + $isediting = $this->page->user_is_editing(); + if (!empty($displayoptions['hidecompletion']) || !isloggedin() || isguestuser() || !$mod->uservisible) { return $output; } @@ -412,49 +416,52 @@ class core_course_renderer extends plugin_renderer_base { $completioninfo = new completion_info($course); } $completion = $completioninfo->is_enabled($mod); + if ($completion == COMPLETION_TRACKING_NONE) { - if ($this->page->user_is_editing()) { + if ($isediting) { $output .= html_writer::span(' ', 'filler'); } return $output; } - $completiondata = $completioninfo->get_data($mod, true); $completionicon = ''; - if ($this->page->user_is_editing()) { + if ($isediting || !$istrackeduser) { switch ($completion) { case COMPLETION_TRACKING_MANUAL : $completionicon = 'manual-enabled'; break; case COMPLETION_TRACKING_AUTOMATIC : $completionicon = 'auto-enabled'; break; } - } else if ($completion == COMPLETION_TRACKING_MANUAL) { - switch($completiondata->completionstate) { - case COMPLETION_INCOMPLETE: - $completionicon = 'manual-n' . ($completiondata->overrideby ? '-override' : ''); - break; - case COMPLETION_COMPLETE: - $completionicon = 'manual-y' . ($completiondata->overrideby ? '-override' : ''); - break; - } - } else { // Automatic - switch($completiondata->completionstate) { - case COMPLETION_INCOMPLETE: - $completionicon = 'auto-n' . ($completiondata->overrideby ? '-override' : ''); - break; - case COMPLETION_COMPLETE: - $completionicon = 'auto-y' . ($completiondata->overrideby ? '-override' : ''); - break; - case COMPLETION_COMPLETE_PASS: - $completionicon = 'auto-pass'; break; - case COMPLETION_COMPLETE_FAIL: - $completionicon = 'auto-fail'; break; + } else { + $completiondata = $completioninfo->get_data($mod, true); + if ($completion == COMPLETION_TRACKING_MANUAL) { + switch($completiondata->completionstate) { + case COMPLETION_INCOMPLETE: + $completionicon = 'manual-n' . ($completiondata->overrideby ? '-override' : ''); + break; + case COMPLETION_COMPLETE: + $completionicon = 'manual-y' . ($completiondata->overrideby ? '-override' : ''); + break; + } + } else { // Automatic + switch($completiondata->completionstate) { + case COMPLETION_INCOMPLETE: + $completionicon = 'auto-n' . ($completiondata->overrideby ? '-override' : ''); + break; + case COMPLETION_COMPLETE: + $completionicon = 'auto-y' . ($completiondata->overrideby ? '-override' : ''); + break; + case COMPLETION_COMPLETE_PASS: + $completionicon = 'auto-pass'; break; + case COMPLETION_COMPLETE_FAIL: + $completionicon = 'auto-fail'; break; + } } } if ($completionicon) { $formattedname = html_entity_decode($mod->get_formatted_name(), ENT_QUOTES, 'UTF-8'); - if ($completiondata->overrideby) { + if (!$isediting && $istrackeduser && $completiondata->overrideby) { $args = new stdClass(); $args->modname = $formattedname; $overridebyuser = \core_user::get_user($completiondata->overrideby, '*', MUST_EXIST); @@ -464,7 +471,7 @@ class core_course_renderer extends plugin_renderer_base { $imgalt = get_string('completion-alt-' . $completionicon, 'completion', $formattedname); } - if ($this->page->user_is_editing() || !has_capability('moodle/course:togglecompletion', $mod->context)) { + if ($isediting || !$istrackeduser || !has_capability('moodle/course:togglecompletion', $mod->context)) { // When editing, the icon is just an image. $completionpixicon = new pix_icon('i/completion-'.$completionicon, $imgalt, '', array('title' => $imgalt, 'class' => 'iconsmall')); diff --git a/lib/completionlib.php b/lib/completionlib.php index 3d8a5e72613..cac848f2f23 100644 --- a/lib/completionlib.php +++ b/lib/completionlib.php @@ -319,9 +319,10 @@ class completion_info { * @return string HTML code for help icon, or blank if not needed */ public function display_help_icon() { - global $PAGE, $OUTPUT; + global $PAGE, $OUTPUT, $USER; $result = ''; - if ($this->is_enabled() && !$PAGE->user_is_editing() && isloggedin() && !isguestuser()) { + if ($this->is_enabled() && !$PAGE->user_is_editing() && $this->is_tracked_user($USER->id) && isloggedin() && + !isguestuser()) { $result .= html_writer::tag('div', get_string('yourprogress','completion') . $OUTPUT->help_icon('completionicons', 'completion'), array('id' => 'completionprogressid', 'class' => 'completionprogress'));