Merge branch 'MDL-65056-master' of git://github.com/abias/moodle
authorSara Arjona <sara@moodle.com>
Wed, 24 Apr 2019 07:18:25 +0000 (09:18 +0200)
committerSara Arjona <sara@moodle.com>
Wed, 24 Apr 2019 07:18:25 +0000 (09:18 +0200)
completion/tests/behat/behat_completion.php
completion/tests/behat/completion_course_page_checkboxes.feature [new file with mode: 0644]
completion/upgrade.txt
course/renderer.php
lib/completionlib.php

index 296f92e..3956959 100644 (file)
@@ -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<activityname_string>(?:[^"]|\\")*)" "(?P<activitytype_string>(?:[^"]|\\")*)" 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<activityname_string>(?:[^"]|\\")*)" "(?P<activitytype_string>(?:[^"]|\\")*)" 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<activityname_string>(?:[^"]|\\")*)" "(?P<activitytype_string>(?:[^"]|\\")*)" 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 (file)
index 0000000..48005ee
--- /dev/null
@@ -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
index db2324d..dc0dbed 100644 (file)
@@ -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 ===
 
index 55f5ebe..9d1439c 100644 (file)
@@ -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('&nbsp;', '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'));
index 3d8a5e7..cac848f 100644 (file)
@@ -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'));