From f057a2aef9b4af9f1cb46f0a077958e0748d7afa Mon Sep 17 00:00:00 2001
From: Mihail Geshoski <mihail@moodle.com>
Date: Wed, 29 Mar 2023 10:59:13 +0800
Subject: [PATCH 1/3] MDL-76445 grade: Helper that returns all gradable users
 in a course

---
 grade/lib.php            | 31 ++++++++++++++++++++
 grade/tests/lib_test.php | 63 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/grade/lib.php b/grade/lib.php
index 1d68991383a..f069d54da72 100644
--- a/grade/lib.php
+++ b/grade/lib.php
@@ -781,6 +781,37 @@ function grade_get_plugin_info($courseid, $active_type, $active_plugin) {
     return $plugin_info;
 }
 
+/**
+ * Load a valid list of gradable users in a course.
+ *
+ * @param int $courseid The course ID.
+ * @param int|null $groupid The group ID (optional).
+ * @return array $users A list of enrolled gradable users.
+ */
+function get_gradable_users(int $courseid, ?int $groupid = null): array {
+    global $CFG;
+
+    $context = context_course::instance($courseid);
+    // Create a graded_users_iterator because it will properly check the groups etc.
+    $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
+    $onlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol) ||
+        !has_capability('moodle/course:viewsuspendedusers', $context);
+
+    $course = get_course($courseid);
+    $gui = new graded_users_iterator($course, null, $groupid);
+    $gui->require_active_enrolment($onlyactiveenrol);
+    $gui->init();
+
+    // Flatten the users.
+    $users = [];
+    while ($user = $gui->next_user()) {
+        $users[$user->user->id] = $user->user;
+    }
+    $gui->close();
+
+    return $users;
+}
+
 /**
  * A simple class containing info about grade plugins.
  * Can be subclassed for special rules
diff --git a/grade/tests/lib_test.php b/grade/tests/lib_test.php
index a8173ef80b1..eedff6ddc07 100644
--- a/grade/tests/lib_test.php
+++ b/grade/tests/lib_test.php
@@ -711,4 +711,67 @@ class lib_test extends \advanced_testcase {
         $this->assertArrayHasKey('assign', $gradeitems2);
         $this->assertArrayHasKey('manual', $gradeitems2);
     }
+
+    /**
+     * Test get_gradable_users() function.
+     *
+     * @covers ::get_gradable_users
+     */
+    public function test_get_gradable_users() {
+        global $DB;
+
+        $this->setAdminUser();
+        $this->resetAfterTest(true);
+
+        $roleteacher = $DB->get_record('role', ['shortname' => 'teacher'], '*', MUST_EXIST);
+
+        // Create a course.
+        $course = $this->getDataGenerator()->create_course();
+        $coursecontext = \context_course::instance($course->id);
+        // Create groups.
+        $group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
+        $group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
+        // Create and enrol a teacher and some students into the course.
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $student3 = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        // Add student1 and student2 to group1.
+        $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $student1->id]);
+        $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $student2->id]);
+        // Add student3 to group2.
+        $this->getDataGenerator()->create_group_member(['groupid' => $group2->id, 'userid' => $student3->id]);
+
+        // Perform a regrade before creating the report.
+        grade_regrade_final_grades($course->id);
+        // Should return all gradable users (only students).
+        $gradableusers = get_gradable_users($course->id);
+        $this->assertEqualsCanonicalizing([$student1->id, $student2->id, $student3->id], array_keys($gradableusers));
+
+        // Now, let's suspend the enrolment of student2.
+        $this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student', 'manual', 0, 0, ENROL_USER_SUSPENDED);
+        // Should return only the active gradable users (student1 and student3).
+        $gradableusers = get_gradable_users($course->id);
+        $this->assertEqualsCanonicalizing([$student1->id, $student3->id], array_keys($gradableusers));
+
+        // Give teacher 'viewsuspendedusers' capability and set a preference to display suspended users.
+        assign_capability('moodle/course:viewsuspendedusers', CAP_ALLOW, $roleteacher->id, $coursecontext, true);
+        set_user_preference('grade_report_showonlyactiveenrol', false, $teacher);
+        accesslib_clear_all_caches_for_unit_testing();
+
+        $this->setUser($teacher);
+        // Should return all gradable users (including suspended enrolments).
+        $gradableusers = get_gradable_users($course->id);
+        $this->assertEqualsCanonicalizing([$student1->id, $student2->id, $student3->id], array_keys($gradableusers));
+
+        // Reactivate the course enrolment of student2.
+        $this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student', 'manual', 0, 0, ENROL_USER_ACTIVE);
+        $this->setAdminUser();
+        // Should return all gradable users from group1 (student1 and student2).
+        $gradableusers = get_gradable_users($course->id, $group1->id);
+        $this->assertEqualsCanonicalizing([$student1->id, $student2->id], array_keys($gradableusers));
+        // Should return all gradable users from group2 (student3).
+        $gradableusers = get_gradable_users($course->id, $group2->id);
+        $this->assertEqualsCanonicalizing([$student3->id], array_keys($gradableusers));
+    }
 }

From e60edbf0cb75fadec8e621dec693eb8915744a17 Mon Sep 17 00:00:00 2001
From: Mihail Geshoski <mihail@moodle.com>
Date: Wed, 29 Mar 2023 12:44:39 +0800
Subject: [PATCH 2/3] MDL-76445 gradereport_user: Usability fixes

---
 grade/report/user/index.php                   |  38 ++++--
 .../user/tests/behat/view_usereport.feature   | 112 +++++++++++++++++-
 2 files changed, 135 insertions(+), 15 deletions(-)

diff --git a/grade/report/user/index.php b/grade/report/user/index.php
index ffd16cac34a..d772779613b 100644
--- a/grade/report/user/index.php
+++ b/grade/report/user/index.php
@@ -106,6 +106,20 @@ if (has_capability('moodle/grade:viewall', $context)) {
         $userid = $USER->id;
     }
 
+    // If there is a stored (last viewed) user in a session variable, bypass the user select zero state and display the
+    // report for that user.
+    $lastvieweduserid = $SESSION->gradereport_user["useritem-{$context->id}"] ?? null;
+    if (is_null($userid) && !is_null($lastvieweduserid)) {
+        $userid = $lastvieweduserid;
+    }
+
+    $gradableusers = get_gradable_users($courseid, $currentgroup);
+    // Validate whether the requested user is a valid gradable user in this course. If, not display the user select
+    // zero state.
+    if (empty($gradableusers) || ($userid && !array_key_exists($userid, $gradableusers))) {
+        $userid = null;
+    }
+
     $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
     $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
     $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context);
@@ -121,20 +135,22 @@ if (has_capability('moodle/grade:viewall', $context)) {
     $gui->init();
 
     if (is_null($userid)) { // Zero state.
-        $report = new gradereport_user\report\user($courseid, $gpr, $context, $USER->id, $viewasuser);
-
-        if (isset($report)) {
-            // Trigger report viewed event.
-            $report->viewed();
-        }
-
         $actionbar = new \gradereport_user\output\action_bar($context, $userview, null, $currentgroup);
         // Print header.
         print_grade_page_head($courseid, 'report', 'user', ' ', false, null, true,
             null, null, null, $actionbar);
 
-        echo $report->output_report_zerostate();
+        if (empty($gradableusers)) { // There are no available gradable users, display a notification.
+            $message = $currentgroup ? get_string('nostudentsingroup') : get_string('nostudentsyet');
+            echo $OUTPUT->notification($message, 'warning', false);
+        } else { // Otherwise, display the zero state template.
+            $report = new gradereport_user\report\user($courseid, $gpr, $context, $USER->id, $viewasuser);
+            echo $report->output_report_zerostate();
+        }
     } else if ($userid == 0) { // Show all reports.
+        // Store the id of the current user item in a session variable which represents the last viewed item.
+        $SESSION->gradereport_user["useritem-{$context->id}"] = $userid;
+
         $actionbar = new \gradereport_user\output\action_bar($context, $userview, 0, $currentgroup);
         print_grade_page_head($courseid, 'report', 'user', ' ', false, null, true,
             null, null, null, $actionbar);
@@ -152,6 +168,9 @@ if (has_capability('moodle/grade:viewall', $context)) {
         }
         $gui->close();
     } else { // Show one user's report.
+        // Store the id of the current user item in a session variable which represents the last viewed item.
+        $SESSION->gradereport_user["useritem-{$context->id}"] = $userid;
+
         $report = new gradereport_user\report\user($courseid, $gpr, $context, $userid, $viewasuser);
         $actionbar = new \gradereport_user\output\action_bar($context, $userview, $report->user->id, $currentgroup);
 
@@ -189,9 +208,6 @@ if (has_capability('moodle/grade:viewall', $context)) {
 if (isset($report)) {
     // Trigger report viewed event.
     $report->viewed();
-} else {
-    echo html_writer::tag('div', '', ['class' => 'clearfix']);
-    echo $OUTPUT->notification(get_string('nostudentsyet'));
 }
 
 echo $OUTPUT->footer();
diff --git a/grade/report/user/tests/behat/view_usereport.feature b/grade/report/user/tests/behat/view_usereport.feature
index 75ee486a29b..7448f4b9bea 100644
--- a/grade/report/user/tests/behat/view_usereport.feature
+++ b/grade/report/user/tests/behat/view_usereport.feature
@@ -1,17 +1,121 @@
-@core @core_grades @gradereport_user
+@core @core_grades @gradereport_user @javascript
 Feature: We can use the user report
   As a user
   I browse to the User report
 
   Background:
     Given the following "courses" exist:
-      | fullname | shortname | category |
-      | Course 1 | C1 | 0 |
+      | fullname | shortname | category | groupmode |
+      | Course 1 | C1        | 0        | 1         |
 
-  @javascript
   Scenario: Verify we can view a user grade report with no users enrolled.
     Given I log in as "admin"
     And I am on "Course 1" course homepage
     And I navigate to "View > User report" in the course gradebook
     And I click on "All users (0)" in the "user" search widget
     Then I should see "There are no students enrolled in this course."
+
+  Scenario: Teacher sees his last viewed user report when navigating back to the gradebook user report.
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | Teacher   | 1        | teacher1@example.com |
+      | teacher2 | Teacher   | 2        | teacher2@example.com |
+      | student1 | Student   | 1        | student1@example.com |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+      | teacher2 | C1     | editingteacher |
+      | student1 | C1     | student        |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > User report" in the course gradebook
+    And I should see "Select a user above to view their report" in the "region-main" "region"
+    And I click on "Student 1" in the "user" search widget
+    And I should see "Student 1" in the "region-main" "region"
+    And I am on "Course 1" course homepage
+    When I navigate to "View > User report" in the course gradebook
+    Then I should not see "Select a user above to view their report" in the "region-main" "region"
+    And I should see "Student 1" in the "region-main" "region"
+    And I log out
+    And I log in as "teacher2"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > User report" in the course gradebook
+    And I should see "Select a user above to view their report" in the "region-main" "region"
+
+  Scenario: Teacher sees his last viewed user report if the user is a part of the the current group.
+    Given the following "groups" exist:
+      | name    | course | idnumber | participation |
+      | Group 1 | C1     | G1       | 1             |
+    And the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | Teacher   | 1        | teacher1@example.com |
+      | student1 | Student   | 1        | student1@example.com |
+      | student2 | Student   | 2        | student2@example.com |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+      | student1 | C1     | student        |
+      | student2 | C1     | student        |
+    And the following "group members" exist:
+      | user     | group |
+      | student2 | G1    |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > User report" in the course gradebook
+    And I click on "Student 2" in the "user" search widget
+    And I navigate to "View > Grader report" in the course gradebook
+    And I click on "Group 1" in the "group" search widget
+    When I navigate to "View > User report" in the course gradebook
+    Then I should see "Student 2" in the "region-main" "region"
+    And I should not see "Select a user above to view their report" in the "region-main" "region"
+
+  Scenario: Teacher does not see the last viewed user if the user is not a part of the the current group.
+    Given the following "groups" exist:
+      | name    | course | idnumber | participation |
+      | Group 1 | C1     | G1       | 1             |
+    And the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | Teacher   | 1        | teacher1@example.com |
+      | student1 | Student   | 1        | student1@example.com |
+      | student2 | Student   | 2        | student2@example.com |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+      | student1 | C1     | student        |
+      | student2 | C1     | student        |
+    And the following "group members" exist:
+      | user     | group |
+      | student2 | G1    |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > User report" in the course gradebook
+    And I click on "Student 1" in the "user" search widget
+    And I navigate to "View > Grader report" in the course gradebook
+    And I click on "Group 1" in the "group" search widget
+    When I navigate to "View > User report" in the course gradebook
+    Then I should see "Select a user above to view their report" in the "region-main" "region"
+    And I should not see "Student 1" in the "region-main" "region"
+
+  Scenario: Teacher does not see his last viewed user report if the user is no longer enrolled in the course.
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | Teacher   | 1        | teacher1@example.com |
+      | student1 | Student   | 1        | student1@example.com |
+      | student2 | Student   | 2        | student2@example.com |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+      | student1 | C1     | student        |
+      | student2 | C1     | student        |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > User report" in the course gradebook
+    And I click on "Student 1" in the "user" search widget
+    And I should see "Student 1" in the "region-main" "region"
+    And I navigate to course participants
+    And I click on "Unenrol" "icon" in the "Student 1" "table_row"
+    And I click on "Unenrol" "button" in the "Unenrol" "dialogue"
+    And I am on "Course 1" course homepage
+    When I navigate to "View > User report" in the course gradebook
+    Then I should see "Select a user above to view their report" in the "region-main" "region"
+    And I should not see "Student 1" in the "region-main" "region"

From 6ceb137f04f76eeac45a8d722246d016ffc767b6 Mon Sep 17 00:00:00 2001
From: Mihail Geshoski <mihail@moodle.com>
Date: Thu, 30 Mar 2023 22:34:53 +0800
Subject: [PATCH 3/3] MDL-76445 gradereport_singleview: Usability fixes

---
 grade/report/singleview/index.php             | 128 +++++++++++++-----
 .../singleview/tests/behat/singleview.feature | 107 ++++++++++++++-
 2 files changed, 197 insertions(+), 38 deletions(-)

diff --git a/grade/report/singleview/index.php b/grade/report/singleview/index.php
index f9867c08c62..4569e3cbf51 100644
--- a/grade/report/singleview/index.php
+++ b/grade/report/singleview/index.php
@@ -33,32 +33,15 @@ $groupid  = optional_param('group', null, PARAM_INT);
 
 // Making this work with profile reports.
 $userid   = optional_param('userid', null, PARAM_INT);
-
-$defaulttype = $userid ? 'user' : 'select';
-
 $itemid = optional_param('itemid', null, PARAM_INT);
-$itemtype = optional_param('item', $defaulttype, PARAM_TEXT);
+$itemtype = optional_param('item', null, PARAM_TEXT);
 $page = optional_param('page', 0, PARAM_INT);
 $perpage = optional_param('perpage', 100, PARAM_INT);
 
 $edit = optional_param('edit', -1, PARAM_BOOL); // Sticky editing mode.
 
-if (empty($itemid) && ($itemtype !== 'user_select' && $itemtype !== 'grade_select')) {
-    $itemid = $userid;
-    $itemtype = $defaulttype;
-}
-
 $courseparams = ['id' => $courseid];
-$pageparams = [
-    'id'        => $courseid,
-    'group'     => $groupid,
-    'userid'    => $userid,
-    'itemid'    => $itemid,
-    'item'      => $itemtype,
-    'page'      => $page,
-    'perpage'   => $perpage,
-];
-$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $pageparams));
+
 $PAGE->set_pagelayout('report');
 $PAGE->set_other_editing_capability('moodle/grade:edit');
 
@@ -68,10 +51,6 @@ if (!$course = $DB->get_record('course', $courseparams)) {
 
 require_login($course);
 
-if (!in_array($itemtype, gradereport_singleview\report\singleview::valid_screens())) {
-    throw new \moodle_exception('notvalid', 'gradereport_singleview', '', $itemtype);
-}
-
 $context = context_course::instance($course->id);
 
 // This is the normal requirements.
@@ -85,6 +64,90 @@ $gpr = new grade_plugin_return([
     'courseid' => $courseid
 ]);
 
+// Last selected report session tracking.
+if (!isset($USER->grade_last_report)) {
+    $USER->grade_last_report = [];
+}
+$USER->grade_last_report[$course->id] = 'singleview';
+// If the item type is not explicitly defined or not valid, try to use the last viewed one (obtain in from the session)
+// or fallback to the user select (zero) state.
+if (!$itemtype || !in_array($itemtype, \gradereport_singleview\report\singleview::valid_screens())) {
+    $itemtype = isset($SESSION->gradereport_singleview["itemtype-{$context->id}"]) ?
+        $SESSION->gradereport_singleview["itemtype-{$context->id}"] : 'user_select';
+}
+
+$currentgroup = $gpr->groupid;
+// To make some other functions work better later.
+if (!$currentgroup) {
+    $currentgroup = null;
+}
+
+$lastvieweduseritemid = $SESSION->gradereport_singleview["useritem-{$context->id}"] ?? null;
+$lastviewedgradeitemid = $SESSION->gradereport_singleview["gradeitem-{$context->id}"] ?? null;
+
+switch ($itemtype) {
+    case 'user_select':
+        // If there is a stored user item (last viewed) in a session variable, bypass the user select zero state
+        // and display this user item. Also, make sure that the stored last viewed user is part of the current
+        // list of gradable users in this course.
+        if ($lastvieweduseritemid && array_key_exists($lastvieweduseritemid, get_gradable_users($courseid, $currentgroup))) {
+            $itemtype = 'user';
+            $itemid = $lastvieweduseritemid;
+        } else {
+            $itemid = null;
+        }
+        break;
+    case 'user':
+        if (is_null($itemid)) {
+            $itemid = $userid ?? $lastvieweduseritemid;
+        }
+        // If the item id (user id) cannot be defined or the user id is not part of the list of gradable users,
+        // display the user select zero state.
+        if (is_null($itemid) || !array_key_exists($itemid, get_gradable_users($courseid, $currentgroup))) {
+            $itemtype = 'user_select';
+        }
+        break;
+    case 'grade_select':
+        // If there is a stored grade item (last viewed) in a session variable, bypass the grade item select zero state
+        // and display this grade item.
+        if ($lastviewedgradeitemid) {
+            $itemtype = 'grade';
+            $itemid = $lastviewedgradeitemid;
+        } else {
+            $itemid = null;
+        }
+        break;
+    case 'grade':
+        // If there is a stored grade item (last viewed) in a session variable, use it.
+        if (is_null($itemid) && $lastviewedgradeitemid) {
+            $itemid = $lastviewedgradeitemid;
+        }
+        $gtree = new grade_tree($courseid, false, false, null, !$CFG->enableoutcomes);
+        $gradeableitems = $gtree->get_items();
+        // The item id (grade item id) cannot be defined, display the grade select zero state.
+        if (is_null($itemid) || !array_key_exists($itemid, $gtree->get_items())) {
+            $itemtype = 'grade_select';
+        }
+        break;
+}
+
+$report = new gradereport_singleview\report\singleview($courseid, $gpr, $context, $itemtype, $itemid);
+
+$pageparams = [
+    'id'        => $courseid,
+    'userid'    => $userid,
+    'itemid'    => $itemid,
+    'item'      => $itemtype,
+    'page'      => $page,
+    'perpage'   => $perpage,
+];
+
+if (!is_null($groupid)) {
+    $pageparams['group'] = $groupid;
+}
+
+$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $pageparams));
+
 // Build editing on/off button for themes that need it.
 $button = '';
 if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
@@ -97,14 +160,6 @@ if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
     $button = $OUTPUT->edit_button(new moodle_url($PAGE->url, $options), 'get');
 }
 
-// Last selected report session tracking.
-if (!isset($USER->grade_last_report)) {
-    $USER->grade_last_report = [];
-}
-$USER->grade_last_report[$course->id] = 'singleview';
-
-$report = new gradereport_singleview\report\singleview($courseid, $gpr, $context, $itemtype, $itemid);
-
 $reportname = $report->screen->heading();
 
 if ($itemtype == 'user' || $itemtype == 'user_select') {
@@ -149,6 +204,11 @@ if ($data = data_submitted()) {
 grade_regrade_final_grades_if_required($course);
 
 echo $report->output();
+// Save the screen state in a session variable as last viewed state.
+$SESSION->gradereport_singleview["itemtype-{$context->id}"] = $itemtype;
+if ($itemid) {
+    $SESSION->gradereport_singleview["{$itemtype}item-{$context->id}"] = $itemid;
+}
 
 if (($itemtype !== 'select') && ($itemtype !== 'grade_select') &&($itemtype !== 'user_select')) {
     $item = (isset($userid)) ? $userid : $itemid;
@@ -157,12 +217,6 @@ if (($itemtype !== 'select') && ($itemtype !== 'grade_select') &&($itemtype !==
     $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
     $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context);
 
-    $currentgroup = $gpr->groupid;
-
-    // To make some other functions work better later.
-    if (!$currentgroup) {
-        $currentgroup = null;
-    }
     $gui = new graded_users_iterator($course, null, $currentgroup);
     $gui->require_active_enrolment($showonlyactiveenrol);
     $gui->init();
diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature
index a202ce4d656..aa3dd31fdf2 100644
--- a/grade/report/singleview/tests/behat/singleview.feature
+++ b/grade/report/singleview/tests/behat/singleview.feature
@@ -7,11 +7,12 @@ Feature: We can use Single view
   Background:
     Given the following "courses" exist:
       | fullname | shortname | category |
-      | Course 1 | C1 | 0 |
+      | Course 1 | C1        | 0        |
     And the following "users" exist:
       | username | firstname | lastname    | email                | idnumber | middlename | alternatename | firstnamephonetic | lastnamephonetic |
       | teacher1 | Teacher   | 1           | teacher1@example.com | t1       |            | fred          |                   |                  |
       | teacher2 | No edit   | 1           | teacher2@example.com | t2       |            | nick          |                   |                  |
+      | teacher3 | Teacher   | 3           | teacher3@example.com | t3       |            | jack          |                   |                  |
       | student1 | Grainne   | Beauchamp   | student1@example.com | s1       | Ann        | Jill          | Gronya            | Beecham          |
       | student2 | Niamh     | Cholmondely | student2@example.com | s2       | Jane       | Nina          | Nee               | Chumlee          |
       | student3 | Siobhan   | Desforges   | student3@example.com | s3       | Sarah      | Sev           | Shevon            | De-forjay        |
@@ -29,6 +30,7 @@ Feature: We can use Single view
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | teacher2 | C1 | teacher |
+      | teacher3 | C1 | teacher |
       | student1 | C1 | student |
       | student2 | C1 | student |
       | student3 | C1 | student |
@@ -165,3 +167,106 @@ Feature: We can use Single view
     And "new grade item 1" "link" should not exist in the "//tbody//tr[position()=1]//td[position()=2]" "xpath_element"
     Then "Category total" "link" should not exist in the "//tbody//tr[position()=2]//td[position()=2]" "xpath_element"
     And "Course total" "link" should not exist in the "//tbody//tr[position()=last()]//td[position()=2]" "xpath_element"
+
+  Scenario: Teacher sees his last viewed singleview report type when navigating back to the gradebook singleview report.
+    Given I navigate to "View > Single view" in the course gradebook
+    And I should see "Select a user above to view all their grades" in the "region-main" "region"
+    And I click on "Grade items" "link"
+    And I should see "Select a grade item above" in the "region-main" "region"
+    And I am on "Course 1" course homepage
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should see "Select a grade item above" in the "region-main" "region"
+    And I log out
+    And I log in as "teacher3"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > Single view" in the course gradebook
+    And I should see "Select a user above to view all their grades" in the "region-main" "region"
+
+  Scenario: Teacher sees his last viewed user report when navigating back to the gradebook singleview report.
+    Given I navigate to "View > Single view" in the course gradebook
+    And I click on "Gronya,Beecham" in the "user" search widget
+    And I should see "Gronya,Beecham" in the "region-main" "region"
+    And I am on "Course 1" course homepage
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should not see "Select a user above to view all their grades" in the "region-main" "region"
+    And I should see "Gronya,Beecham" in the "region-main" "region"
+    And I log out
+    And I log in as "teacher3"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > Single view" in the course gradebook
+    And I should see "Select a user above to view all their grades" in the "region-main" "region"
+
+  Scenario: Teacher sees his last viewed grade item report when navigating back to the gradebook singleview report.
+    Given I navigate to "View > Single view" in the course gradebook
+    And I click on "Grade items" "link"
+    And I click on "Test assignment one" in the "grade" search widget
+    And I should see "Test assignment one" in the "region-main" "region"
+    And I am on "Course 1" course homepage
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should not see "Select a grade item above" in the "region-main" "region"
+    And I should see "Test assignment one" in the "region-main" "region"
+    And I log out
+    And I log in as "teacher3"
+    And I am on "Course 1" course homepage
+    And I navigate to "View > Single view" in the course gradebook
+    And I should see "Select a user above to view all their grades" in the "region-main" "region"
+
+  Scenario: Teacher sees his last viewed user report if the user is a part of the the current group.
+    Given the following "groups" exist:
+      | name    | course | idnumber | participation |
+      | Group 1 | C1     | G1       | 1             |
+    And the following "group members" exist:
+      | user     | group |
+      | student2 | G1    |
+    And I am on the "Course 1" "course editing" page
+    And I expand all fieldsets
+    And I set the field "Group mode" to "Visible groups"
+    And I press "Save and display"
+    And I navigate to "View > Single view" in the course gradebook
+    And I click on "Nee,Chumlee" in the "user" search widget
+    And I navigate to "View > Grader report" in the course gradebook
+    And I click on "Group 1" in the "group" search widget
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should see "Nee,Chumlee" in the "region-main" "region"
+    And I should not see "Select a user above to view all their grades" in the "region-main" "region"
+
+  Scenario: Teacher does not see his last viewed user report if the user is not a part of the the current group.
+    Given the following "groups" exist:
+      | name    | course | idnumber | participation |
+      | Group 1 | C1     | G1       | 1             |
+    And the following "group members" exist:
+      | user     | group |
+      | student2 | G1    |
+    And I am on "Course 1" course homepage
+    And I navigate to "Settings" in current page administration
+    And I expand all fieldsets
+    And I set the field "Group mode" to "Visible groups"
+    And I press "Save and display"
+    And I navigate to "View > Single view" in the course gradebook
+    And I click on "Gronya,Beecham" in the "user" search widget
+    And I navigate to "View > Grader report" in the course gradebook
+    And I click on "Group 1" in the "group" search widget
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should see "Select a user above to view all their grades" in the "region-main" "region"
+    And I should not see "Gronya,Beecham" in the "region-main" "region"
+
+  Scenario: Teacher does not see his last viewed user report if that user is no longer enrolled in the course.
+    Given I navigate to "View > Single view" in the course gradebook
+    And I click on "Gronya,Beecham" in the "user" search widget
+    And I navigate to course participants
+    And I click on "Unenrol" "icon" in the "Gronya,Beecham" "table_row"
+    And I click on "Unenrol" "button" in the "Unenrol" "dialogue"
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should see "Select a user above to view all their grades" in the "region-main" "region"
+    And I should not see "Gronya,Beecham" in the "region-main" "region"
+
+  Scenario: Teacher does not see his last viewed grade item report if the item no longer exists in the course.
+    Given I navigate to "View > Single view" in the course gradebook
+    And I click on "Grade items" "link"
+    And I click on "Test assignment four" in the "grade" search widget
+    And I am on "Course 1" course homepage with editing mode on
+    And I delete "Test assignment four" activity
+    And I run all adhoc tasks
+    When I navigate to "View > Single view" in the course gradebook
+    Then I should see "Select a grade item above" in the "region-main" "region"
+    And I should not see "Test grade item" in the "region-main" "region"