first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,147 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Behat steps definitions for drag and drop onto image.
*
* @package gradereport_grader
* @category test
* @copyright 2015 Oakland University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
use Behat\Mink\Exception\ExpectationException as ExpectationException,
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
/**
* Steps definitions related with the drag and drop onto image question type.
*
* @copyright 2015 Oakland University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_gradereport_grader extends behat_base {
/**
* Gets the user id from its name.
*
* @throws Exception
* @param string $name
* @return int
*/
protected function get_user_id($name) {
global $DB;
$names = explode(' ', $name);
if (!$id = $DB->get_field('user', 'id', array('firstname' => $names[0], 'lastname' => $names[1]))) {
throw new Exception('The specified user with username "' . $name . '" does not exist');
}
return $id;
}
/**
* Gets the grade item id from its name.
*
* @deprecated since 4.2
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @throws Exception
* @param string $itemname
* @return int
*/
protected function get_grade_item_id($itemname) {
global $DB;
debugging('behat_gradereport_grader::get_grade_item_id() is deprecated, please use' .
' behat_grades::get_grade_item_id() instead.', DEBUG_DEVELOPER);
if ($id = $DB->get_field('grade_items', 'id', array('itemname' => $itemname))) {
return $id;
}
// The course total is a special case.
if ($itemname === "Course total") {
if (!$id = $DB->get_field('grade_items', 'id', array('itemtype' => 'course'))) {
throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist');
}
return $id;
}
// Find a category with the name.
if ($catid = $DB->get_field('grade_categories', 'id', array('fullname' => $itemname))) {
if ($id = $DB->get_field('grade_items', 'id', array('iteminstance' => $catid))) {
return $id;
}
}
throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist');
}
/**
* Clicks on given user menu.
*
* @Given /^I click on user menu "([^"]*)"$/
* @param string $student
*/
public function i_click_on_user_menu(string $student) {
$xpath = $this->get_user_selector($student);
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
/**
* Gets unique xpath selector for a user.
*
* @throws Exception
* @param string $student
* @return string
*/
protected function get_user_selector(string $student): string {
$userid = $this->get_user_id($student);
return "//table[@id='user-grades']//*[@data-type='user'][@data-id='" . $userid . "']";
}
/**
* Clicks on given user profile field menu.
*
* @Given /^I click on user profile field menu "([^"]*)"$/
* @param string $field
*/
public function i_click_on_user_profile_field_menu(string $field) {
$xpath = "//table[@id='user-grades']//*[@data-type='" . mb_strtolower($field) . "']";
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
/**
* Return the list of partial named selectors.
*
* @return array
*/
public static function get_partial_named_selectors(): array {
return [
new behat_component_named_selector(
'collapse search',
[".//*[contains(concat(' ', @class, ' '), ' collapsecolumndropdown ')]"]
),
];
}
}
@@ -0,0 +1,250 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
use Behat\Gherkin\Node\TableNode;
require_once(__DIR__ . '/../../../../../lib/behat/behat_deprecated_base.php');
/**
* Steps definitions that are now deprecated and will be removed in the next releases.
*
* This file only contains the steps that previously were in the behat_*.php files in the SAME DIRECTORY.
* When deprecating steps from other components or plugins, create a behat_COMPONENT_deprecated.php
* file in the same directory where the steps were defined.
*
* @package gradereport_grader
* @category test
* @copyright 2023 Ilya Tregubov
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_gradereport_grader_deprecated extends behat_deprecated_base {
/**
* Remove focus for a grade value cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Given /^I click away from student "([^"]*)" and grade item "([^"]*)" feedback$/
* @param string $student
* @param string $itemname
*/
public function i_click_away_from_student_and_grade_feedback($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_click_away_from_student_and_grade_feedback']);
$xpath = $this->get_student_and_grade_feedback_selector($student, $itemname);
$this->execute('behat_general::i_take_focus_off_field', array($this->escape($xpath), 'xpath_element'));
}
/**
* Look for a feedback editing field.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^I should see a feedback field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_see_feedback_field($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_should_see_feedback_field']);
$xpath = $this->get_student_and_grade_feedback_selector($student, $itemname);
$this->execute('behat_general::should_be_visible', array($this->escape($xpath), 'xpath_element'));
}
/**
* Look for a lack of the feedback editing field.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^I should not see a feedback field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_not_see_feedback_field($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_should_not_see_feedback_field']);
$xpath = $this->get_student_and_grade_feedback_selector($student, $itemname);
$this->execute('behat_general::should_not_exist', array($this->escape($xpath), 'xpath_element'));
}
/**
* Gets xpath for a particular student/grade item feedback cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_feedback_selector($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::get_student_and_grade_feedback_selector']);
$cell = $this->get_student_and_grade_cell_selector($student, $itemname);
return $cell . "//input[contains(@id, 'feedback_') or @name='ajaxfeedback']";
}
/**
* Click a given user grade cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Given /^I click on student "([^"]*)" for grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_click_on_student_and_grade_item($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_click_on_student_and_grade_item']);
$xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
/**
* Remove focus for a grade value cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Given /^I click away from student "([^"]*)" and grade item "([^"]*)" value$/
* @param string $student
* @param string $itemname
*/
public function i_click_away_from_student_and_grade_value($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_click_away_from_student_and_grade_value']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::i_take_focus_off_field', array($this->escape($xpath), 'xpath_element'));
}
/**
* Checks grade values with or without a edit box.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^the grade for "([^"]*)" in grade item "([^"]*)" should match "([^"]*)"$/
* @throws Exception
* @throws ElementNotFoundException
* @param string $student
* @param string $itemname
* @param string $value
*/
public function the_grade_should_match($student, $itemname, $value) {
$this->deprecated_message(['behat_gradereport_grader::the_grade_should_match']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$gradefield = $this->getSession()->getPage()->find('xpath', $xpath);
if (!empty($gradefield)) {
// Get the field.
$fieldtype = behat_field_manager::guess_field_type($gradefield, $this->getSession());
if (!$fieldtype) {
throw new Exception('Could not get field type for grade field "' . $itemname . '"');
}
$field = behat_field_manager::get_field_instance($fieldtype, $gradefield, $this->getSession());
if (!$field->matches($value)) {
$fieldvalue = $field->get_value();
throw new ExpectationException(
'The "' . $student . '" and "' . $itemname . '" grade is "' . $fieldvalue . '", "' . $value . '" expected' ,
$this->getSession()
);
}
} else {
// If there isn't a form field, just search for contents.
$valueliteral = behat_context_helper::escape($value);
$xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
$xpath .= "[contains(normalize-space(.)," . $valueliteral . ")]";
$node = $this->getSession()->getDriver()->find($xpath);
if (empty($node)) {
$locatorexceptionmsg = 'Cell for "' . $student . '" and "' . $itemname . '" with value "' . $value . '"';
throw new ElementNotFoundException($this->getSession(), $locatorexceptionmsg, null, $xpath);
}
}
}
/**
* Look for a grade editing field.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^I should see a grade field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_see_grade_field($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_should_see_grade_field']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::should_be_visible', array($this->escape($xpath), 'xpath_element'));
}
/**
* Look for a lack of the grade editing field.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^I should not see a grade field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_not_see_grade_field($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_should_not_see_grade_field']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::should_not_exist', array($this->escape($xpath), 'xpath_element'));
}
/**
* Gets unique xpath selector for a student/grade item combo.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_cell_selector($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::get_student_and_grade_cell_selector']);
$itemid = 'u' . $this->get_user_id($student) . 'i' . $this->get_grade_item_id($itemname);
return "//table[@id='user-grades']//td[@id='" . $itemid . "']";
}
/**
* Gets xpath for a particular student/grade item grade value cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_value_selector($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::get_student_and_grade_value_selector']);
$cell = $this->get_student_and_grade_cell_selector($student, $itemname);
return $cell . "//*[contains(@id, 'grade_') or @name='ajaxgrade']";
}
}
@@ -0,0 +1,288 @@
@core @javascript @gradereport @gradereport_grader
Feature: Within the grader report, test that we can collapse columns
In order to reduce usage of visual real estate
As a teacher
I need to be able to change how the report is displayed
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "grade categories" exist:
| fullname | course |
| Some cool grade category | C1 |
And the following "custom profile fields" exist:
| datatype | shortname | name |
| text | enduro | Favourite enduro race |
And the following "users" exist:
| username | firstname | lastname | email | idnumber | phone1 | phone2 | department | institution | city | country |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 | 1234567892 | 1234567893 | ABC1 | ABCD | Perth | AU |
| student1 | Student | 1 | student1@example.com | s1 | 3213078612 | 8974325612 | ABC1 | ABCD | Hanoi | VN |
| student2 | Dummy | User | student2@example.com | s2 | 4365899871 | 7654789012 | ABC2 | ABCD | Tokyo | JP |
| student3 | User | Example | student3@example.com | s3 | 3243249087 | 0875421745 | ABC2 | ABCD | Olney | GB |
| student4 | User | Test | student4@example.com | s4 | 0987532523 | 2149871323 | ABC3 | ABCD | Tokyo | JP |
| student5 | Turtle | Manatee | student5@example.com | s5 | 1239087780 | 9873623589 | ABC3 | ABCD | Perth | AU |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "activities" exist:
| activity | course | idnumber | name | gradecategory |
| assign | C1 | a1 | Test assignment one | Some cool grade category |
| assign | C1 | a3 | Test assignment three | Some cool grade category |
And the following "activities" exist:
| activity | course | idnumber | name |
| assign | C1 | a2 | Test assignment two |
| assign | C1 | a4 | Test assignment four |
And the following config values are set as admin:
| showuseridentity | idnumber,email,city,country,phone1,phone2,department,institution,profile_field_enduro |
And I change window size to "large"
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
Scenario: An admin collapses a user info column and then reloads the page to find the column still collapsed
Given "Email" "text" in the "First name / Last name" "table_row" should be visible
And I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
And I click on user profile field menu "profile_field_enduro"
And I choose "Collapse" in the open action menu
And "Favourite enduro race" "text" in the "First name / Last name" "table_row" should not be visible
When I reload the page
Then "Email" "text" in the "First name / Last name" "table_row" should not be visible
# Check that the collapsed column is only for the user that set it.
And I am on the "Course 1" "Course" page logged in as "admin"
And I change window size to "large"
And I navigate to "View > Grader report" in the course gradebook
And "Email" "text" in the "First name / Last name" "table_row" should be visible
Scenario: A teacher collapses a grade item column and then reloads the page to find the column still collapsed
Given "Test assignment one" "link" in the "First name / Last name" "table_row" should be visible
And I click on grade item menu "Test assignment one" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And "Test assignment one" "link" in the "First name / Last name" "table_row" should not be visible
When I reload the page
And "Test assignment one" "link" in the "First name / Last name" "table_row" should not be visible
Scenario: When a user collapses a column, inform them within the report and tertiary nav area
Given I click on grade item menu "Test assignment one" of type "gradeitem" on "grader" page
When I choose "Collapse" in the open action menu
And "Test assignment one" "link" in the "First name / Last name" "table_row" should not be visible
Then I should see "Expand column Test assignment one"
And I should see "Collapsed columns 1"
Scenario: Collapsed columns can have their name searched and triggered to expand but the contents are not searched
Given "ID number" "text" in the "First name / Last name" "table_row" should be visible
And I click on user profile field menu "idnumber"
And I choose "Collapse" in the open action menu
# Opens the tertiary trigger button.
And I click on "Collapsed columns" "combobox"
# This is checking that the column name search dropdown exists.
And I wait until "Search collapsed columns" "field" exists
# Default state contains the collapsed column names.
And I should see "ID number"
# Search for a column that was not hidden.
When I set the field "Search collapsed columns" to "Email"
And I should see "No results for \"Email\""
# Search for a ID number value inside the column that was hidden.
Then I set the field "Search collapsed columns" to "s5"
And I should see "No results for \"s5\""
# Search for a column that was hidden.
And I set the field "Search collapsed columns" to "ID"
And I should see "ID number"
Scenario: Expand multiple columns at once
Given I click on grade item menu "Test assignment one" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And I click on grade item menu "Test assignment two" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And I click on grade item menu "Test assignment three" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And I click on grade item menu "Test assignment four" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone1"
And I choose "Collapse" in the open action menu
And I click on "Collapsed columns" "combobox"
# This is checking that the column name search dropdown exists.
When I wait until "Search collapsed columns" "field" exists
And I click on "Test assignment one" "checkbox" in the "form" "gradereport_grader > collapse search"
And I click on "Test assignment three" "checkbox" in the "form" "gradereport_grader > collapse search"
And I click on "Phone" "checkbox" in the "form" "gradereport_grader > collapse search"
And I click on "Expand" "button" in the "form" "gradereport_grader > collapse search"
And "Test assignment one" "link" in the "First name / Last name" "table_row" should be visible
And "Test assignment three" "link" in the "First name / Last name" "table_row" should be visible
And "Phone" "text" in the "First name / Last name" "table_row" should be visible
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
And "Test assignment two" "link" in the "First name / Last name" "table_row" should not be visible
And "Test assignment four" "link" in the "First name / Last name" "table_row" should not be visible
Scenario: If there is only one collapsed column it expands
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
When I press "Expand column Email"
And I wait until the page is ready
Then "Email" "text" in the "First name / Last name" "table_row" should be visible
Scenario: When a grade item is collapsed, the grade category is shown alongside the column name.
Given I click on grade item menu "Test assignment one" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And I click on grade item menu "Test assignment two" of type "gradeitem" on "grader" page
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And "Test assignment one" "link" in the "First name / Last name" "table_row" should not be visible
And "Test assignment two" "link" in the "First name / Last name" "table_row" should not be visible
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
# Opens the tertiary trigger button.
When I click on "Collapsed columns" "combobox"
# This is checking that the column name search dropdown exists.
And I wait until "Search collapsed columns" "field" exists
# Add ordering test as well.
And I should see "Test assignment one" in the "form" "gradereport_grader > collapse search"
And I should see "Some cool grade category" in the "form" "gradereport_grader > collapse search"
And I should see "Test assignment two" in the "form" "gradereport_grader > collapse search"
And I should see "Course 1" in the "form" "gradereport_grader > collapse search"
And I should see "Email" in the "form" "gradereport_grader > collapse search"
And I should not see "Category div" in the "form" "gradereport_grader > collapse search"
Scenario: Toggling edit mode should not show all collapsed columns
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
When I turn editing mode on
And I wait until the page is ready
Then "Email" "text" in the "First name / Last name" "table_row" should not be visible
Scenario: Resulting columns from hidden grade categories cant be collapsed
# Hiding columns already tested elsewhere, これはこれ、それはそれ。
Given I click on grade item menu "Some cool grade category" of type "category" on "grader" page
And I choose "Show totals only" in the open action menu
And I should not see "Test assignment name 1"
And I should see "Some cool grade category total"
When I click on grade item menu "Some cool grade category" of type "category" on "grader" page
Then I should not see "Collapse" in the ".dropdown-menu.show" "css_element"
@accessibility
Scenario: A teacher can manipulate the report display in an accessible way
# Hide a bunch of columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone1"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone2"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Basic tests for the page.
When I click on "Collapsed columns" "combobox"
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
# Move onto general keyboard navigation testing.
Then the focused element is "Search collapsed columns" "field"
And I press the escape key
And the focused element is "Collapsed columns" "combobox"
And I click on "Collapsed columns" "combobox"
# Lets check the tabbing order.
And I set the field "Search collapsed columns" to "phone"
And I wait until "Mobile phone" "checkbox" exists
And I press the tab key
And the focused element is "Clear search input" "button" in the ".dropdown-menu.show" "css_element"
And I press the escape key
And I press the tab key
# The course grade category menu.
And the focused element is "Cell actions" "button"
# Tab over to the collapsed columns.
And I click on user profile field menu "city"
And I press the escape key
And I press the tab key
And the focused element is "Expand column Country" "button"
And I press the enter key
And I press the tab key
And the focused element is "Expand column Phone" "button"
And I press the enter key
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
And "Phone" "text" in the "First name / Last name" "table_row" should be visible
And "Mobile phone" "text" in the "First name / Last name" "table_row" should not be visible
And "Country" "text" in the "First name / Last name" "table_row" should be visible
# Ensure that things did not start failing after we did some manipulation.
And the page should meet accessibility standards
And the page should meet "wcag131, wcag141, wcag412" accessibility standards
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
Scenario: Collapsed columns persist across paginated pages
# Hide a bunch of columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone1"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone2"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Ensure we are ready to move onto the next step.
When I should see "Collapsed columns 4"
# Confirm our columns are hidden.
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
And "Phone" "text" in the "First name / Last name" "table_row" should not be visible
And "Mobile phone" "text" in the "First name / Last name" "table_row" should not be visible
And "Country" "text" in the "First name / Last name" "table_row" should not be visible
# Navigate to the next paginated page and ensure our columns are still hidden.
Then I set the field "perpage" to "100"
And I should see "Collapsed columns 4"
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
And "Phone" "text" in the "First name / Last name" "table_row" should not be visible
And "Mobile phone" "text" in the "First name / Last name" "table_row" should not be visible
And "Country" "text" in the "First name / Last name" "table_row" should not be visible
Scenario: If a column is actively sorted and then collapsed the active sort on the page should become First name
# This behaviour is inline with other tables where we collapse columns that are sortable.
Given I click on user profile field menu "Email"
And I choose "Descending" in the open action menu
And I wait to be redirected
And I click on user profile field menu "Email"
When I choose "Collapse" in the open action menu
And I wait to be redirected
And "Email" "text" in the "First name / Last name" "table_row" should not be visible
Then "Dummy User" "table_row" should appear before "Student 1" "table_row"
And "Student 1" "table_row" should appear before "Turtle Manatee" "table_row"
And "Turtle Manatee" "table_row" should appear before "User Example" "table_row"
Scenario: If multiple columns are collapsed, then all the user to expand all of them at once
# Hide a bunch of columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone1"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone2"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Ensure we are ready to move onto the next step.
And I wait until "Collapsed columns" "combobox" exists
When I click on "Collapsed columns" "combobox"
And I click on "Select all" "checkbox"
And I click on "Expand" "button" in the "form" "gradereport_grader > collapse search"
# All of the previously collapsed columns should now be visible.
And "Email" "text" in the "First name / Last name" "table_row" should be visible
And "Phone" "text" in the "First name / Last name" "table_row" should be visible
And "Mobile phone" "text" in the "First name / Last name" "table_row" should be visible
And "Country" "text" in the "First name / Last name" "table_row" should be visible
Scenario: If multiple columns are collapsed, when selecting all and then unselecting an option, the select all is then unchecked
# Hide some columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Ensure we are ready to move onto the next step.
And I wait until "Collapsed columns" "combobox" exists
When I click on "Collapsed columns" "combobox"
And I click on "Select all" "checkbox"
And I click on "Email" "checkbox" in the "form" "gradereport_grader > collapse search"
# The select all option should now be unchecked, Checking the form or option role is iffy with behat so we use the id.
Then the field "Select all" matches value ""
@@ -0,0 +1,111 @@
@core @core_grades @gradereport_grader @javascript
Feature: Group searching functionality within the grader report.
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 |
| student1 | Student | 1 | student1@example.com | s1 |
| student2 | Student | 2 | student2@example.com | s2 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "groups" exist:
| name | course | idnumber |
| Default group | C1 | dg |
| Group 2 | C1 | g2 |
| Tutor group | C1 | tg |
| Marker group | C1 | mg |
And the following "group members" exist:
| user | group |
| student1 | dg |
| student2 | g2 |
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
Scenario: A teacher can see the 'group' search widget only when group mode is enabled in the course
Given ".groupsearchwidget" "css_element" should exist
And I am on the "C1" "course editing" page
And I set the following fields to these values:
| id_groupmode | No groups |
And I press "Save and display"
When I navigate to "View > Grader report" in the course gradebook
Then ".groupsearchwidget" "css_element" should not exist
Scenario: A teacher can search for and find a group to display
Given I confirm "Tutor group" in "group" search within the gradebook widget exists
And I confirm "Marker group" in "group" search within the gradebook widget exists
When I set the field "Search groups" to "tutor"
And I wait until "Marker group" "option_role" does not exist
Then I confirm "Tutor group" in "group" search within the gradebook widget exists
And I confirm "Marker group" in "group" search within the gradebook widget does not exist
And I click on "Tutor group" in the "group" search widget
# The search input remains in the field on reload this is in keeping with other search implementations.
And I click on ".groupsearchwidget" "css_element"
And the field "Search groups" matches value "tutor"
Then I set the field "Search groups" to "Turtle"
And I should see "No results for \"Turtle\""
Scenario: A teacher can only see the group members in the 'user' search widget after selecting a group option
# Confirm that all users are initially displayed in the 'user' search widget.
Given I set the field "Search users" to "Student"
And I confirm "Student 1" in "user" search within the gradebook widget exists
And I confirm "Student 2" in "user" search within the gradebook widget exists
# Select a particular group from the 'group' search widget.
When I click on "Default group" in the "group" search widget
# Confirm that only users which are members of the selected group are displayed in the 'user' search widget.
And I set the field "Search users" to "Student"
Then I confirm "Student 1" in "user" search within the gradebook widget exists
And I confirm "Student 2" in "user" search within the gradebook widget does not exist
And I click on "Tutor group" in the "group" search widget
And I set the field "Search users" to "Student"
And I confirm "Student 1" in "user" search within the gradebook widget does not exist
And I confirm "Student 2" in "user" search within the gradebook widget does not exist
And I click on "All participants" in the "group" search widget
And I set the field "Search users" to "Student"
And I confirm "Student 1" in "user" search within the gradebook widget exists
And I confirm "Student 2" in "user" search within the gradebook widget exists
@accessibility
Scenario: A teacher can set focus and search using the input with a keyboard
Given I click on ".groupsearchwidget" "css_element"
# Basic tests for the page.
And the page should meet accessibility standards
And the page should meet "wcag131, wcag141, wcag412" accessibility standards
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
# Move onto general keyboard navigation testing.
And I click on "Search groups" "field"
And I wait until "Default group" "option_role" exists
And I press the down key
And the focused element is "Search groups" "field"
And ".active" "css_element" should exist in the "All participants" "option_role"
And I press the up key
And the focused element is "Search groups" "field"
And ".active" "css_element" should exist in the "Tutor group" "option_role"
And I press the down key
And the focused element is "Search groups" "field"
And ".active" "css_element" should exist in the "All participants" "option_role"
Then I set the field "Search groups" to "Goodmeme"
And I wait until "Tutor group" "option_role" does not exist
And I press the down key
And the focused element is "Search groups" "field"
And I navigate to "View > User report" in the course gradebook
And I click on ".groupsearchwidget" "css_element"
And I set the field "Search groups" to "Tutor"
And I wait until "All participants" "option_role" does not exist
And I press the down key
And the focused element is "Search groups" "field"
And ".active" "css_element" should exist in the "Tutor group" "option_role"
# Lets check the tabbing order.
And I set the field "Search groups" to "Marker"
And I wait until "Marker group" "option_role" exists
And I press the tab key
And the focused element is "Clear search input" "button"
And I press the enter key
And I wait until the page is ready
And ".groupsearchwidget" "css_element" should exist
@@ -0,0 +1,63 @@
Feature: Locking Grade Items and Categories in Gradebook
In order to ensure that grade items and categories can be securely locked in the gradebook,
As a teacher,
I need to perform locking actions and verify the locking status.
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname |
| teacher1 | Teacher | 1 |
| student1 | Student | 1 |
| student2 | Student | 2 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "grade categories" exist:
| fullname | course |
| Category 1 | C1 |
And the following "grade items" exist:
| itemname | course | gradecategory |
| Manual grade 1 | C1 | Category 1 |
| Manual grade 2 | C1 | Category 1 |
And the following "grade items" exist:
| itemname | course |
| Manual grade 3 | C1 |
@javascript
Scenario: Locking and unlocking a grade item preserves individual student locks
Given I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
And I turn editing mode on
And I change window size to "large"
When I click on "Manual grade 1" "core_grades > grade_actions" in the "Student 1" "table_row"
And I choose "Lock" in the open action menu
And I click on grade item menu "Manual grade 1" of type "gradeitem" on "grader" page
And I choose "Lock" in the open action menu
And I click on grade item menu "Manual grade 1" of type "gradeitem" on "grader" page
And I choose "Unlock" in the open action menu
Then "Locked" "icon" should exist in the "Student 1" "table_row"
And "Locked" "icon" should not exist in the "Student 2" "table_row"
@javascript
Scenario: Locking and unlocking a grade item through editing form preserves individual student locks
Given I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
And I turn editing mode on
And I change window size to "large"
When I click on "Manual grade 1" "core_grades > grade_actions" in the "Student 1" "table_row"
And I choose "Edit grade" in the open action menu
And I set the field "Locked" to "1"
And I press "Save changes"
And I click on grade item menu "Manual grade 1" of type "gradeitem" on "grader" page
And I choose "Edit grade item" in the open action menu
And I set the field "Locked" to "1"
And I click on "Save" "button" in the "Edit grade item" "dialogue"
And I click on grade item menu "Manual grade 1" of type "gradeitem" on "grader" page
And I choose "Edit grade item" in the open action menu
And I set the field "Locked" to "0"
And I click on "Save" "button" in the "Edit grade item" "dialogue"
Then "Locked" "icon" should exist in the "Student 1" "table_row"
And "Locked" "icon" should not exist in the "Student 2" "table_row"
@@ -0,0 +1,87 @@
@gradereport @gradereport_grader
Feature: grader report pagination
In order to consume the content of the report better
As a teacher
I need the report to be paginated
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
@javascript
Scenario: Default is used when teachers have no preference yet
Given "41" "users" exist with the following data:
| username | student[count] |
| firstname | Student |
| lastname | [count] |
| email | student[count]@example.com |
And "41" "course enrolments" exist with the following data:
| user | student[count] |
| course | C1 |
| role |student |
When I am on the "Course 1" "Course" page logged in as "teacher1"
And I navigate to "View > Grader report" in the course gradebook
Then the field "perpage" matches value "20"
# Add 3 to the expected number because there are 2 header and 1 footer rows.
And I should see "23" node occurrences of type "tr" in the "user-grades" "table"
And I should see "3" in the ".stickyfooter .pagination" "css_element"
And I should not see "4" in the ".stickyfooter .pagination" "css_element"
@javascript
Scenario: Teachers can have their preference for the number of students
Given the following "courses" exist:
| fullname | shortname |
| Course 2 | C2 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C2 | editingteacher |
When I am on the "Course 1" "Course" page logged in as "teacher1"
And I navigate to "View > Grader report" in the course gradebook
And I set the field "perpage" to "100"
And I am on the "Course 2" "Course" page
And I navigate to "View > Grader report" in the course gradebook
Then the field "perpage" matches value "100"
@javascript
Scenario: Teachers can change the number of students shown on the report
Given "101" "users" exist with the following data:
| username | student[count] |
| firstname | Student |
| lastname | [count] |
| email | student[count]@example.com |
And "101" "course enrolments" exist with the following data:
| user | student[count] |
| course | C1 |
| role |student |
When I am on the "Course 1" "Course" page logged in as "teacher1"
And I navigate to "View > Grader report" in the course gradebook
And I set the field "perpage" to "100"
# Add 3 to the expected number because there are 2 header and 1 footer rows.
Then I should see "103" node occurrences of type "tr" in the "user-grades" "table"
And I should see "2" in the ".stickyfooter .pagination" "css_element"
And I should not see "3" in the ".stickyfooter .pagination" "css_element"
@javascript
Scenario: The pagination bar is only displayed when there is more than one page
Given "21" "users" exist with the following data:
| username | student[count] |
| firstname | Student |
| lastname | [count] |
| email | student[count]@example.com |
And "21" "course enrolments" exist with the following data:
| user | student[count] |
| course | C1 |
| role |student |
When I am on the "Course 1" "Course" page logged in as "teacher1"
And I navigate to "View > Grader report" in the course gradebook
# By default, we have 20 students per page.
Then ".stickyfooter .pagination" "css_element" should exist
And I set the field "perpage" to "100"
Then ".stickyfooter .pagination" "css_element" should not exist
@@ -0,0 +1,79 @@
@gradereport @gradereport_grader
Feature: We can sort grades/user fields on the grader report
In order to manage grades on grader report
As a teacher
I need to be able to sort grades or user fields.
Background:
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | StudentA | 2 | d@example.com |
| student2 | StudentB | 4 | a@example.com |
| student3 | StudentC | 3 | c@example.com |
| student4 | StudentD | 1 | b@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
And the following "activities" exist:
| activity | course | section | name | intro | assignsubmission_onlinetext_enabled | submissiondrafts |
| assign | C1 | 1 | Test assignment name 1 | Submit your online text | 1 | 0 |
And the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| Test assignment name 1 | student1 | This is a submission for assignment 1 |
| Test assignment name 1 | student2 | This is a submission for assignment 1 |
| Test assignment name 1 | student3 | This is a submission for assignment 1 |
| Test assignment name 1 | student4 | This is a submission for assignment 1 |
And the following "grade items" exist:
| itemname | grademin | grademax | course |
| Manual grade | 20 | 40 | C1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name 1 | student1 | 80 |
| Test assignment name 1 | student2 | 40 |
| Test assignment name 1 | student3 | 60 |
And I log in as "teacher1"
@javascript
Scenario: Sort grades or user fields on grader report by using cell action menu
When I am on "Course 1" course homepage with editing mode on
And I navigate to "View > Grader report" in the course gradebook
# Default sorting is lastname ascending.
And "StudentD 1" "table_row" should appear before "StudentA 2" "table_row"
And "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
And "StudentC 3" "table_row" should appear before "StudentB 4" "table_row"
# Sort by grades in descending order.
And I click on grade item menu "Test assignment name 1" of type "gradeitem" on "grader" page
And I choose "Descending" in the open action menu
And I wait until the page is ready
Then "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
And "StudentC 3" "table_row" should appear before "StudentB 4" "table_row"
And "StudentB 4" "table_row" should appear before "StudentD 1" "table_row"
# Sort by grades in ascending order.
And I click on grade item menu "Test assignment name 1" of type "gradeitem" on "grader" page
And I choose "Ascending" in the open action menu
And I wait until the page is ready
Then "StudentD 1" "table_row" should appear before "StudentB 4" "table_row"
And "StudentB 4" "table_row" should appear before "StudentC 3" "table_row"
And "StudentC 3" "table_row" should appear before "StudentA 2" "table_row"
# Sort by email in ascending order.
And I click on user profile field menu "email"
And I choose "Ascending" in the open action menu
And I wait until the page is ready
Then "StudentB 4" "table_row" should appear before "StudentD 1" "table_row"
And "StudentD 1" "table_row" should appear before "StudentC 3" "table_row"
And "StudentC 3" "table_row" should appear before "StudentA 2" "table_row"
And I click on user profile field menu "email"
# Sort by email in descending order.
And I choose "Descending" in the open action menu
And I wait until the page is ready
Then "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
And "StudentC 3" "table_row" should appear before "StudentD 1" "table_row"
And "StudentD 1" "table_row" should appear before "StudentB 4" "table_row"
@@ -0,0 +1,105 @@
@gradereport @gradereport_grader
Feature: We can change what we are viewing on the grader report
In order to check the expected results are displayed
As a teacher
I need to assign grades and check that they display correctly in the gradebook when switching between views.
Background:
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
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 "activities" exist:
| activity | course | section | name | intro | assignsubmission_onlinetext_enabled | submissiondrafts |
| assign | C1 | 1 | Test assignment name 1 | Submit your online text | 1 | 0 |
| assign | C1 | 1 | Test assignment name 2 | submit your online text | 1 | 0 |
And the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| Test assignment name 1 | student1 | This is a submission for assignment 1 |
| Test assignment name 2 | student1 | This is a submission for assignment 2 |
And the following "grade items" exist:
| itemname | grademin | grademax | course |
| Manual grade | 20 | 40 | C1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name 1 | student1 | 80 |
| Test assignment name 2 | student1 | 90 |
| Manual grade | student1 | 30 |
And I log in as "teacher1"
@javascript
Scenario: View and minimise the grader report containing hidden activities
When I am on "Course 1" course homepage with editing mode on
And I open "Test assignment name 2" actions menu
And I choose "Hide" in the open action menu
And I am on "Course 1" course homepage with editing mode off
And I navigate to "View > Grader report" in the course gradebook
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- | -4- | -5- | -6- |
| Student 1 | student1@example.com | 80 | 90 | 30 | 170 |
And I click on grade item menu "Course 1" of type "course" on "grader" page
And I choose "Show totals only" in the open action menu
And I should not see "Test assignment name 1" in the "user-grades" "table"
And I should not see "Test assignment name 2" in the "user-grades" "table"
And I should not see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- |
| Student 1 | student1@example.com | 170 |
And I click on grade item menu "Course 1" of type "course" on "grader" page
And I click on "Show grades only" "link"
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- | -4- | -5- |
| Student 1 | student1@example.com | 80 | 90 | 30 |
@javascript @skip_chrome_zerosize
Scenario: Minimise the grader report containing hidden activities without the 'moodle/grade:viewhidden' capability
Given I am on "Course 1" course homepage with editing mode on
And I open "Test assignment name 2" actions menu
And I choose "Hide" in the open action menu
And the following "role capability" exists:
| role | editingteacher |
| moodle/grade:viewhidden | prevent |
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
Then I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- | -4- | -5- | -6- |
| Student 1 | student1@example.com | 80 | - | 30 | 105.71 |
And I click on grade item menu "Course 1" of type "course" on "grader" page
And I choose "Show totals only" in the open action menu
And I should not see "Test assignment name 1" in the "user-grades" "table"
And I should not see "Test assignment name 2" in the "user-grades" "table"
And I should not see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- |
| Student 1 | student1@example.com | 105.71 |
And I click on grade item menu "Course 1" of type "course" on "grader" page
When I click on "Show grades only" "link"
Then I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- | -4- | -5- |
| Student 1 | student1@example.com | 80 | - | 30 |
@@ -0,0 +1,219 @@
@core @javascript @gradereport_grader
Feature: Within the grader report, test that we can open our generic filter dropdown component
In order to filter down the users on the page
As a teacher
I need to be able to see the filter and select a combination of parameters
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 |
| student1 | Student | 1 | student1@example.com | s1 |
| student2 | Dummy | User | student2@example.com | s2 |
| student3 | User | Example | student3@example.com | s3 |
| student4 | User | Test | student4@example.com | s4 |
| student5 | Turtle | Manatee | student5@example.com | s5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "activities" exist:
| activity | course | idnumber | name |
| assign | C1 | a1 | Test assignment one |
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
Scenario: A teacher can open the filter component
Given I should see "Filter by name"
When I click on "Filter by name" "combobox"
Then I should see "27" node occurrences of type "input" in the "First name" "core_grades > initials bar"
And I should see "27" node occurrences of type "input" in the "Last name" "core_grades > initials bar"
And "input[data-action=cancel]" "css_element" should exist
And "input[data-action=save]" "css_element" should exist
Scenario: A teacher can filter the grader report to limit users reported
Given I click on "Filter by name" "combobox"
And I wait until "input[data-action=save]" "css_element" exists
When I select "D" in the "First name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
# We should only have one user that matches the "D" first name
Then the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| User Test |
| Turtle Manatee |
# Test filtering on last name
# Business logic: If all is selected, we will not show it i.e. First (D) and NOT First (D) Last (All)
And I click on "First (D)" "combobox"
And I select "All" in the "First name" "core_grades > initials bar"
And I select "M" in the "Last name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
# We should only have one user that matches the "T" first name
And the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| User Test |
| Dummy User |
# Test filtering on first && last name
And I click on "Last (M)" "combobox"
And I select "U" in the "First name" "core_grades > initials bar"
And I select "T" in the "Last name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
# We should only have one user that matches the "T" first name
And the following should exist in the "user-grades" table:
| -1- |
| User Test |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| Dummy User |
| Turtle Manatee |
# Final cheeky check to ensure our button matches.
And I click on "First (U) Last (T)" "combobox"
Scenario: A teacher can quickly tell that a filter is applied to the current table
Given I click on "Filter by name" "combobox"
And I wait until "input[data-action=save]" "css_element" exists
When I select "T" in the "First name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
Then I should see "First (T)"
# Check if removing the filter, removes the highlight and user notice of applied filters
And I click on "First (T)" "combobox"
And I wait until "input[data-action=save]" "css_element" exists
And I select "All" in the "First name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
# Check if the name button indicates if a filter is active
And I should see "Filter by name"
And I should not see "First (T)"
Scenario: A teacher can close the filter either by clicking close or clicking off the dropdown
Given I click on "Filter by name" "combobox"
And "input[data-action=save]" "css_element" should be visible
When I click on "input[data-action=cancel]" "css_element"
Then "input[data-action=save]" "css_element" should not be visible
# Click off the drop down
And I click on "Filter by name" "combobox"
And "input[data-action=save]" "css_element" should be visible
And I change window size to "large"
And I click on user profile field menu "fullname"
And "input[data-action=save]" "css_element" should not be visible
Scenario: A teacher using a language besides english can reset the initials bar
Given the following "language customisations" exist:
| component | stringid | value |
| core | all | |
And I click on "Filter by name" "combobox"
And "input[data-action=save]" "css_element" should be visible
And I select "T" in the "First name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
And I click on "First (T)" "combobox"
And I wait until "input[data-action=save]" "css_element" exists
When I select "" in the "First name" "core_grades > initials bar"
And I press "Apply"
And I wait to be redirected
Then I should not see "First () Last ()"
And the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
| Student 1 |
| User Example |
| User Test |
| Turtle Manatee |
Scenario: A teacher can search and then filter by first or last name
Given I set the field "Search users" to "Student 1"
And I click on "Student 1" in the "user" search widget
And I click on "Filter by name" "combobox"
And I select "S" in the "First name" "core_grades > initials bar"
When I press "Apply"
And the field "Search users" matches value "Student 1"
Then the following should exist in the "user-grades" table:
| -1- | -2- | -3- |
| Student 1 | student1@example.com | - |
And the following should not exist in the "user-grades" table:
| -1- | -2- | -3- |
| Teacher 1 | teacher1@example.com | - |
| Dummy User | student2@example.com | - |
| User Example | student3@example.com | - |
| User Test | student4@example.com | - |
| Turtle Manatee | student5@example.com | - |
And I click on "First (S)" "combobox"
And I select "M" in the "First name" "core_grades > initials bar"
And I press "Apply"
And the following should not exist in the "user-grades" table:
| -1- | -2- | -3- |
| Student 1 | student1@example.com | - |
| Teacher 1 | teacher1@example.com | - |
| Dummy User | student2@example.com | - |
| User Example | student3@example.com | - |
| User Test | student4@example.com | - |
| Turtle Manatee | student5@example.com | - |
Scenario: A teacher can search for all users then filter with the initials bar
Given I set the field "Search users" to "User"
And I click on "View all results (3)" "option_role"
And the following should exist in the "user-grades" table:
| -1- | -2- | -3- |
| User Example | student3@example.com | - |
| User Test | student4@example.com | - |
| Dummy User | student2@example.com | - |
And the following should not exist in the "user-grades" table:
| -1- | -2- | -3- |
| Student 1 | student1@example.com | - |
| Teacher 1 | teacher1@example.com | - |
| Turtle Manatee | student5@example.com | - |
When I click on "Filter by name" "combobox"
And I select "E" in the "Last name" "core_grades > initials bar"
And I press "Apply"
Then the following should exist in the "user-grades" table:
| -1- | -2- | -3- |
| User Example | student3@example.com | - |
And the following should not exist in the "user-grades" table:
| -1- | -2- | -3- |
| Student 1 | student1@example.com | - |
| Teacher 1 | teacher1@example.com | - |
| Dummy User | student2@example.com | - |
| User Test | student4@example.com | - |
| Turtle Manatee | student5@example.com | - |
# This can be expanded for left/right/home & end keys but will have to be done in conjunction with the non mini render.
@accessibility
Scenario: A teacher can set focus and navigate the filter with the keyboard
Given the page should meet accessibility standards
And the page should meet "wcag131, wcag141, wcag412" accessibility standards
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
And I click on "Filter by name" "combobox"
And "input[data-action=save]" "css_element" should be visible
And the focused element is "All" "button" in the "First name" "core_grades > initials bar"
When I press the tab key
Then the focused element is "input[value=A]" "css_element" in the "First name" "core_grades > initials bar"
And I press the tab key
And the focused element is "input[value=B]" "css_element" in the "First name" "core_grades > initials bar"
@@ -0,0 +1,441 @@
@core @core_grades @javascript @gradereport @gradereport_grader
Feature: Within the grader report, test that we can search for users
In order to find specific users in the course gradebook
As a teacher
I need to be able to see the search input and trigger the search somehow
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email | idnumber | phone1 | phone2 | department | institution | city | country |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 | 1234567892 | 1234567893 | ABC1 | ABCD | Perth | AU |
| student1 | Student | 1 | student1@example.com | s1 | 3213078612 | 8974325612 | ABC1 | ABCD | Hanoi | VN |
| student2 | Dummy | User | student2@example.com | s2 | 4365899871 | 7654789012 | ABC2 | ABCD | Tokyo | JP |
| student3 | User | Example | student3@example.com | s3 | 3243249087 | 0875421745 | ABC2 | ABCD | Olney | GB |
| student4 | User | Test | student4@example.com | s4 | 0987532523 | 2149871323 | ABC3 | ABCD | Tokyo | JP |
| student5 | Turtle | Manatee | student5@example.com | s5 | 1239087780 | 9873623589 | ABC3 | ABCD | Perth | AU |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "groups" exist:
| name | course | idnumber |
| Default group | C1 | dg |
And the following "group members" exist:
| user | group |
| student5 | dg |
And the following "activities" exist:
| activity | course | idnumber | name |
| assign | C1 | a1 | Test assignment one |
And the following config values are set as admin:
| showuseridentity | idnumber,email,city,country,phone1,phone2,department,institution |
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
And I change window size to "large"
Scenario: A teacher can view and trigger the user search
# Check the placeholder text
Given I should see "Search users"
# Confirm the search is currently inactive and results are unfiltered.
And the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
| Student 1 |
| User Example |
| User Test |
| Dummy User |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
When I set the field "Search users" to "Turtle"
And I wait until "View all results (1)" "option_role" exists
And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists
And I confirm "User Example" in "user" search within the gradebook widget does not exist
And I click on "Turtle Manatee" "list_item"
# Business case: This will trigger a page reload and can not dynamically update the table.
And I wait until the page is ready
Then the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| User Test |
| Dummy User |
And I set the field "Search users" to "Turt"
And I wait until "View all results (1)" "option_role" exists
And I click on "Clear search input" "button" in the ".user-search" "css_element"
And "View all results (1)" "option_role" should not be visible
Scenario: A teacher can search the grader report to find specified users
# Case: Standard search.
Given I click on "Dummy" in the "user" search widget
And the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| User Test |
| Turtle Manatee |
# Case: No users found.
When I set the field "Search users" to "Plagiarism"
And I should see "No results for \"Plagiarism\""
# Table remains unchanged as the user had no results to select from the dropdown.
And the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| User Test |
| Turtle Manatee |
# Case: Multiple users found and select only one result.
Then I set the field "Search users" to "User"
And I wait until "View all results (3)" "option_role" exists
And I confirm "Dummy User" in "user" search within the gradebook widget exists
And I confirm "User Example" in "user" search within the gradebook widget exists
And I confirm "User Test" in "user" search within the gradebook widget exists
And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist
# Check if the matched field names (by lines) includes some identifiable info to help differentiate similar users.
And I confirm "User (student2@example.com)" in "user" search within the gradebook widget exists
And I confirm "User (student3@example.com)" in "user" search within the gradebook widget exists
And I confirm "User (student4@example.com)" in "user" search within the gradebook widget exists
And I click on "Dummy User" "list_item"
And I wait until the page is ready
And the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Example |
| User Test |
| Turtle Manatee |
# Business case: When searching with multiple partial matches, show the matches in the dropdown + a "View all results for (Bob)"
# Business case cont. When pressing enter with multiple partial matches, behave like when you select the "View all results for (Bob)"
# Case: Multiple users found and select all partial matches.
And I set the field "Search users" to "User"
And I wait until "View all results (3)" "option_role" exists
# Dont need to check if all users are in the dropdown, we checked that earlier in this test.
And I click on "View all results (3)" "option_role"
And I wait until the page is ready
And the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
| User Example |
| User Test |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| Turtle Manatee |
And I click on "Clear" "link" in the ".user-search" "css_element"
And I wait until the page is ready
And the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
| Student 1 |
| User Example |
| User Test |
| Dummy User |
Scenario: A teacher can quickly tell that a search is active on the current table
When I click on "Turtle" in the "user" search widget
# The search input should contain the name of the user we have selected, so that it is clear that the result pertains to a specific user.
Then the field "Search users" matches value "Turtle Manatee"
# Test if we can then further retain the turtle result set and further filter from there.
And I set the field "Search users" to "Turtle plagiarism"
And "Turtle Manatee" "list_item" should not be visible
And I should see "No results for \"Turtle plagiarism\""
Scenario: A teacher can search for values besides the users' name
Given I set the field "Search users" to "student5@example.com"
And I wait until "View all results (1)" "option_role" exists
And "Turtle Manatee" "list_item" should exist
And I set the field "Search users" to "@example.com"
And I wait until "View all results (5)" "option_role" exists
# Note: All learners match this email & showing emails is current default.
And I confirm "Dummy User" in "user" search within the gradebook widget exists
And I confirm "User Example" in "user" search within the gradebook widget exists
And I confirm "User Test" in "user" search within the gradebook widget exists
And I confirm "Student 1" in "user" search within the gradebook widget exists
And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists
# Search on the country field.
When I set the field "Search users" to "JP"
And I wait until "Turtle Manatee" "list_item" does not exist
And I confirm "Dummy User" in "user" search within the gradebook widget exists
And I confirm "User Test" in "user" search within the gradebook widget exists
# Search on the city field.
And I set the field "Search users" to "Hanoi"
And I wait until "User Test" "list_item" does not exist
Then I confirm "Student 1" in "user" search within the gradebook widget exists
# Search on the institution field.
And I set the field "Search users" to "ABCD"
And I wait until "Dummy User" "list_item" exists
And I confirm "User Example" in "user" search within the gradebook widget exists
And I confirm "User Test" in "user" search within the gradebook widget exists
And I confirm "Student 1" in "user" search within the gradebook widget exists
And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists
# Search on the department field.
And I set the field "Search users" to "ABC3"
And I wait until "User Example" "list_item" does not exist
And I confirm "User Test" in "user" search within the gradebook widget exists
And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists
# Search on the phone1 field.
And I set the field "Search users" to "4365899871"
And I wait until "User Test" "list_item" does not exist
And I confirm "Dummy User" in "user" search within the gradebook widget exists
# Search on the phone2 field.
And I set the field "Search users" to "2149871323"
And I wait until "Dummy User" "list_item" does not exist
And I confirm "User Test" in "user" search within the gradebook widget exists
# Search on the institution field then press enter to show the record set.
And I set the field "Search users" to "ABC"
And I wait until "Turtle Manatee" "list_item" exists
And I confirm "Dummy User" in "user" search within the gradebook widget exists
And I confirm "User Example" in "user" search within the gradebook widget exists
And I confirm "User Test" in "user" search within the gradebook widget exists
And I confirm "Student 1" in "user" search within the gradebook widget exists
And I press the down key
And I press the enter key
And I wait "1" seconds
And the following should exist in the "user-grades" table:
| -1- |
| Student 1 |
And the following should not exist in the "user-grades" table:
| -1- |
| User Example |
| User Test |
| Dummy User |
| Turtle Manatee |
| Teacher 1 |
@accessibility
Scenario: A teacher can set focus and search using the input are with a keyboard
Given I set the field "Search users" to "ABC"
And the focused element is "Search users" "field"
And I wait until "Turtle Manatee" "option_role" exists
# Basic tests for the page.
When the page should meet accessibility standards
And the page should meet "wcag131, wcag141, wcag412" accessibility standards
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
And I press the down key
And ".active" "css_element" should exist in the "Student 1" "option_role"
And I press the up key
And ".active" "css_element" should exist in the "View all results (5)" "option_role"
And I press the down key
And ".active" "css_element" should exist in the "Student 1" "option_role"
And I press the escape key
And the focused element is "Search users" "field"
Then I set the field "Search users" to "Goodmeme"
And I press the down key
And the focused element is "Search users" "field"
And I navigate to "View > Grader report" in the course gradebook
And I set the field "Search users" to "ABC"
And I wait until "Turtle Manatee" "option_role" exists
And I press the down key
And ".active" "css_element" should exist in the "Student 1" "option_role"
# Lets check the tabbing order.
And I set the field "Search users" to "ABC"
And I click on "Search users" "field"
And I wait until "Turtle Manatee" "option_role" exists
And I press the tab key
And the focused element is "Clear search input" "button"
And I press the tab key
And ".groupsearchwidget" "css_element" should exist
# Ensure we can interact with the input & clear search options with the keyboard.
# Space & Enter have the same handling for triggering the two functionalities.
And I set the field "Search users" to "User"
And I press the up key
And I press the enter key
And I wait to be redirected
# Sometimes with behat we get unattached nodes causing spurious failures.
And I wait "1" seconds
And the following should exist in the "user-grades" table:
| -1- |
| Dummy User |
| User Example |
| User Test |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| Turtle Manatee |
And I set the field "Search users" to "ABC"
And I wait until "Turtle Manatee" "option_role" exists
And I press the tab key
And the focused element is "Clear search input" "button"
And I press the enter key
And I wait until the page is ready
And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist
Scenario: Once a teacher searches, it'll apply the currently set filters and inform the teacher as such
# Set up a basic filtering case.
Given I click on "Filter by name" "combobox"
And I select "U" in the "First name" "core_grades > initials bar"
And I select "E" in the "Last name" "core_grades > initials bar"
And I press "Apply"
And I wait until the page is ready
And the following should exist in the "user-grades" table:
| -1- |
| User Example |
And the following should not exist in the "user-grades" table:
| -1- |
| Teacher 1 |
| Student 1 |
| User Test |
| Dummy User |
| Turtle Manatee |
# Begin the search checking if we are adhering the filters.
When I set the field "Search users" to "Turtle"
Then I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist
Scenario: A teacher can reset the search and filters all at once
Given I set the field "Search users" to "Turtle"
And I click on "Turtle Manatee" "option_role"
And I wait until the page is ready
And the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
And I click on "Filter by name" "combobox"
And I select "T" in the "First name" "core_grades > initials bar"
And I select "M" in the "Last name" "core_grades > initials bar"
And the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
And I click on "Default group" in the "group" search widget
And the following should exist in the "user-grades" table:
| -1- |
| Turtle Manatee |
And I wait until the page is ready
When I click on "Clear all" "link" in the ".tertiary-navigation" "css_element"
And I wait until the page is ready
Then the field "Search users" matches value ""
Scenario: As a teacher I can dynamically find users whilst ignoring pagination
Given "42" "users" exist with the following data:
| username | students[count] |
| firstname | Student |
| lastname | s[count] |
| email | students[count]@example.com |
And "42" "course enrolments" exist with the following data:
| user | students[count] |
| course | C1 |
| role |student |
And I reload the page
And the field "perpage" matches value "20"
When I set the field "Search users" to "42"
# One of the users' phone numbers also matches.
And I wait until "View all results (2)" "option_role" exists
Then I confirm "Student s42" in "user" search within the gradebook widget exists
Scenario: As a teacher I save grades using search and pagination
Given "42" "users" exist with the following data:
| username | students[count] |
| firstname | Student |
| lastname | test[count] |
| email | students[count]@example.com |
And "42" "course enrolments" exist with the following data:
| user | students[count] |
| course | C1 |
| role |student |
And I reload the page
And I turn editing mode on
And the field "perpage" matches value "20"
And I click on user profile field menu "fullname"
And I choose "Ascending" in the open action menu
And I wait until the page is ready
# Search for a single user on second page and save grades.
When I set the field "Search users" to "test32"
And I wait until "View all results (1)" "option_role" exists
And I click on "Student test32" "option_role"
And I wait until the page is ready
And I give the grade "80.00" to the user "Student test32" for the grade item "Test assignment one"
And I press "Save changes"
And I wait until the page is ready
Then the field "Search users" matches value "Student test32"
And the following should exist in the "user-grades" table:
| -1- |
| Student test32 |
And I set the field "Search users" to "test3"
And I click on "Student test31" "option_role"
And I wait until the page is ready
And I give the grade "70.00" to the user "Student test31" for the grade item "Test assignment one"
And I press "Save changes"
And I wait until the page is ready
Then the field "Search users" matches value "Student test31"
And the following should exist in the "user-grades" table:
| -1- |
| Student test31 |
And the following should not exist in the "user-grades" table:
| -1- |
| Student test32 |
And I click on "Clear" "link" in the ".user-search" "css_element"
And I wait until the page is ready
And the following should not exist in the "user-grades" table:
| -1- |
| Student test32 |
And I click on "2" "link" in the ".stickyfooter .pagination" "css_element"
And I wait until the page is ready
And the following should exist in the "user-grades" table:
| -1- |
| Student test31 |
| Student test32 |
# Set grade for a single user on second page without search and save grades.
And I give the grade "70.00" to the user "Student test31" for the grade item "Test assignment one"
And I press "Save changes"
And I wait until the page is ready
# We are still on second page.
And the following should exist in the "user-grades" table:
| -1- |
| Student test31 |
| Student test32 |
# Search for multiple users on second page and save grades.
And I set the field "Search users" to "test3"
And I wait until "View all results (11)" "option_role" exists
And I click on "View all results (11)" "option_role"
And I wait until the page is ready
And I give the grade "10.00" to the user "Student test32" for the grade item "Test assignment one"
And I give the grade "20.00" to the user "Student test30" for the grade item "Test assignment one"
And I give the grade "30.00" to the user "Student test31" for the grade item "Test assignment one"
And I give the grade "40.00" to the user "Student test3" for the grade item "Test assignment one"
And I press "Save changes"
And I wait until the page is ready
Then the field "Search users" matches value "test3"
And the following should exist in the "user-grades" table:
| -1- |
| Student test3 |
| Student test30 |
| Student test31 |
| Student test32 |
And the following should not exist in the "user-grades" table:
| -1- |
| Student test1 |
| Student test2 |
| Student test4 |
@@ -0,0 +1,113 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for the gradereport_grader implementation of the privacy API.
*
* @package gradereport_grader
* @category test
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_grader\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\local\metadata\collection;
use core_privacy\local\request\writer;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\deletion_criteria;
use gradereport_grader\privacy\provider;
/**
* Unit tests for the gradereport_grader implementation of the privacy API.
*
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider_test extends \core_privacy\tests\provider_testcase {
/**
* Basic setup for these tests.
*/
public function setUp(): void {
$this->resetAfterTest(true);
}
/**
* Ensure that export_user_preferences returns no data if the user has no data.
*/
public function test_export_user_preferences_not_defined(): void {
$user = \core_user::get_user_by_username('admin');
provider::export_user_preferences($user->id);
$writer = writer::with_context(\context_system::instance());
$this->assertFalse($writer->has_any_data());
}
/**
* Ensure that export_user_preferences returns single preferences.
* These preferences can be set on each course, but the value is shared in the whole site.
*/
public function test_export_user_preferences_single(): void {
// Create test user, add some preferences.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
set_user_preference('grade_report_meanselection', GRADE_REPORT_MEAN_GRADED, $user);
set_user_preference('grade_report_studentsperpage', 50, $user);
// Switch to admin user (so we can validate preferences of our test user are still exported).
$this->setAdminUser();
// Validate exported data for our test user.
provider::export_user_preferences($user->id);
$context = \context_user::instance($user->id);
/** @var \core_privacy\tests\request\content_writer $writer */
$writer = writer::with_context($context);
$this->assertTrue($writer->has_any_data());
$prefs = $writer->get_user_preferences('gradereport_grader');
$this->assertCount(2, (array) $prefs);
$this->assertEquals(get_string('meangraded', 'grades'), $prefs->grade_report_meanselection->value);
$this->assertEquals(50, $prefs->grade_report_studentsperpage->value);
}
/**
* Ensure that export_user_preferences returns preferences.
*/
public function test_export_user_preferences_multiple(): void {
// Create a course and add a user preference.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
$course = $this->getDataGenerator()->create_course();
$collapsed = serialize(['aggregatesonly' => array(), 'gradesonly' => array()]);
set_user_preference('grade_report_grader_collapsed_categories'.$course->id, $collapsed, $user);
// Validate exported data.
provider::export_user_preferences($user->id);
$context = \context_user::instance($user->id);
/** @var \core_privacy\tests\request\content_writer $writer */
$writer = writer::with_context($context);
$this->assertTrue($writer->has_any_data());
$prefs = $writer->get_user_preferences('gradereport_grader');
$this->assertCount(1, (array) $prefs);
$this->assertEquals(
get_string('privacy:request:preference:grade_report_grader_collapsed_categories', 'gradereport_grader', ['name' => $course->fullname]),
$prefs->grade_report_grader_collapsed_categories->description
);
}
}