From cfa91962d161ad527d15ef41170e43bab41a7268 Mon Sep 17 00:00:00 2001 From: John Okely Date: Tue, 30 Sep 2014 14:09:46 +0800 Subject: [PATCH] MDL-47243 behat: Add data generators for gradeitems scales and outcomes --- .../behat/tests/behat/data_generators.feature | 125 +++++++++++++++++- lib/testing/generator/data_generator.php | 72 +++++++++- lib/tests/behat/behat_data_generators.php | 73 +++++++++- 3 files changed, 265 insertions(+), 5 deletions(-) diff --git a/admin/tool/behat/tests/behat/data_generators.feature b/admin/tool/behat/tests/behat/data_generators.feature index c9758f20320..2b32cb096e6 100644 --- a/admin/tool/behat/tests/behat/data_generators.feature +++ b/admin/tool/behat/tests/behat/data_generators.feature @@ -185,6 +185,12 @@ Feature: Set up contextual data for tests | url | Test url name | Test url description | C1 | url1 | | wiki | Test wiki name | Test wiki description | C1 | wiki1 | | workshop | Test workshop name | Test workshop description | C1 | workshop1 | + And the following "scales" exist: + | name | scale | + | Test Scale 1 | Disappointing, Good, Very good, Excellent | + And the following "activities" exist: + | activity | name | intro | course | idnumber | grade | + | assign | Test assignment name with scale | Test assignment description | C1 | assign1 | Test Scale 1 | When I log in as "admin" And I follow "Course 1" Then I should see "Test assignment name" @@ -214,6 +220,10 @@ Feature: Set up contextual data for tests And I should see "Test workshop name" And I follow "Test assignment name" And I should see "Test assignment description" + And I follow "C1" + And I follow "Test assignment name with scale" + And I follow "Edit settings" + And the field "Type" matches value "Scale" @javascript Scenario: Add relations between users and groups @@ -297,13 +307,124 @@ Feature: Set up contextual data for tests | Course 1 | C1 | And the following "grade categories" exist: | fullname | course | - | Grade category 1 | C1| + | Grade category 1 | C1 | And the following "grade categories" exist: | fullname | course | gradecategory | - | Grade sub category 2 | C1 | Grade category 1| + | Grade sub category 2 | C1 | Grade category 1 | When I log in as "admin" And I follow "Courses" And I follow "Course 1" And I navigate to "Grades" node in "Course administration" Then I should see "Grade category 1" And I should see "Grade sub category 2" + + Scenario: Add a bunch of grade items + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "grade categories" exist: + | fullname | course | + | Grade category 1 | C1 | + And the following "grade categories" exist: + | fullname | course | gradecategory | + | Grade sub category 2 | C1 | Grade category 1 | + And the following "grade items" exist: + | itemname | course | + | Test Grade Item 1 | C1 | + And the following "grade items" exist: + | itemname | course | gradecategory | + | Test Grade Item 2 | C1 | Grade category 1 | + | Test Grade Item 3 | C1 | Grade sub category 2 | + When I log in as "admin" + And I follow "Course 1" + And I follow "Grades" + And I expand "Setup" node + And I follow "Categories and items" + Then I should see "Test Grade Item 1" + And I follow "Edit Test Grade Item 1" + And I expand all fieldsets + And I should see "Course 1" + And I press "Cancel" + And I should see "Grade category 1" + And I should see "Test Grade Item 2" + And I follow "Edit Test Grade Item 2" + And I expand all fieldsets + And I should see "Grade category 1" + And I press "Cancel" + And I should see "Grade sub category 2" + And I should see "Test Grade Item 3" + And I follow "Edit Test Grade Item 3" + And I expand all fieldsets + And I should see "Grade sub category 2" + And I press "Cancel" + + Scenario: Add a bunch of scales + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "scales" exist: + | name | scale | + | Test Scale 1 | Disappointing, Good, Very good, Excellent | + When I log in as "admin" + And I follow "Course 1" + And I follow "Grades" + And I follow "Scales" + Then I should see "Test Scale 1" + And I should see "Disappointing, Good, Very good, Excellent" + + Scenario: Add a bunch of outcomes + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "scales" exist: + | name | scale | + | Test Scale 1 | Disappointing, Good, Very good, Excellent | + And the following "grade outcomes" exist: + | fullname | shortname | scale | + | Grade outcome 1 | OT1 | Test Scale 1 | + And the following "grade outcomes" exist: + | fullname | shortname | course | scale | + | Grade outcome 2 | OT2 | C1 | Test Scale 1 | + When I log in as "admin" + And I set the following administration settings values: + | Enable outcomes | 1 | + And I follow "Home" + And I follow "Course 1" + And I follow "Outcomes" + Then I should see "Grade outcome 1" in the "#addoutcomes" "css_element" + And I should see "Grade outcome 2" in the "#removeoutcomes" "css_element" + And I follow "Edit outcomes" + And the following should exist in the "generaltable" table: + | Full name | Short name | Scale | + | Grade outcome 2 | OT2 | Test Scale 1 | + + Scenario: Add a bunch of outcome grade items + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "scales" exist: + | name | scale | + | Test Scale 1 | Disappointing, Good, Very good, Excellent | + And the following "grade outcomes" exist: + | fullname | shortname | course | scale | + | Grade outcome 1 | OT1 | C1 | Test Scale 1 | + And the following "grade categories" exist: + | fullname | course | + | Grade category 1 | C1 | + And the following "grade items" exist: + | itemname | course | outcome | gradecategory | + | Test Outcome Grade Item 1 | C1 | OT1 | Grade category 1 | + When I log in as "admin" + And I set the following administration settings values: + | Enable outcomes | 1 | + And I follow "Home" + And I follow "Course 1" + And I follow "Grades" + And I expand "Setup" node + And I follow "Categories and items" + Then I should see "Test Outcome Grade Item 1" + And I follow "Edit Test Outcome Grade Item 1" + And the field "Outcome" matches value "Grade outcome 1" + And I expand all fieldsets + And "//div[contains(@class, 'fitem')]/div[contains(@class, 'fitemtitle')]/div[contains(@class, fstaticlabel) and contains(., 'Grade category')]/../../div[contains(@class, 'felement') and contains(., 'Grade category 1')]" "xpath_element" should exist + And I press "Cancel" diff --git a/lib/testing/generator/data_generator.php b/lib/testing/generator/data_generator.php index 55ef5df6c97..2bca043d7a1 100644 --- a/lib/testing/generator/data_generator.php +++ b/lib/testing/generator/data_generator.php @@ -34,7 +34,12 @@ defined('MOODLE_INTERNAL') || die(); * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class testing_data_generator { + /** @var int The number of grade categories created */ protected $gradecategorycounter = 0; + /** @var int The number of grade items created */ + protected $gradeitemcounter = 0; + /** @var int The number of grade outcomes created */ + protected $gradeoutcomecounter = 0; protected $usercounter = 0; protected $categorycount = 0; protected $cohortcount = 0; @@ -914,7 +919,6 @@ EOD; global $CFG; $this->gradecategorycounter++; - $i = $this->gradecategorycounter; $record = (array)$record; @@ -923,7 +927,7 @@ EOD; } if (!isset($record['fullname'])) { - $record['fullname'] = 'Grade category ' . $i; + $record['fullname'] = 'Grade category ' . $this->gradecategorycounter; } // For gradelib classes. @@ -941,4 +945,68 @@ EOD; $gradecategory->update_from_db(); return $gradecategory->get_record_data(); } + + /** + * Create a grade_item. + * + * @param array|stdClass $record + * @return stdClass the grade item record + */ + public function create_grade_item($record = null) { + global $CFG; + require_once("$CFG->libdir/gradelib.php"); + + $this->gradeitemcounter++; + + if (!isset($record['itemtype'])) { + $record['itemtype'] = 'manual'; + } + + if (!isset($record['itemname'])) { + $record['itemname'] = 'Grade item ' . $this->gradeitemcounter; + } + + if (isset($record['outcomeid'])) { + $outcome = new grade_outcome(array('id' => $record['outcomeid'])); + $record['scaleid'] = $outcome->scaleid; + } + if (isset($record['scaleid'])) { + $record['gradetype'] = GRADE_TYPE_SCALE; + } else if (!isset($record['gradetype'])) { + $record['gradetype'] = GRADE_TYPE_VALUE; + } + + // Create new grade item in this course. + $gradeitem = new grade_item($record, false); + $gradeitem->insert(); + + $gradeitem->update_from_db(); + return $gradeitem->get_record_data(); + } + + /** + * Create a grade_outcome. + * + * @param array|stdClass $record + * @return stdClass the grade outcome record + */ + public function create_grade_outcome($record = null) { + global $CFG; + + $this->gradeoutcomecounter++; + $i = $this->gradeoutcomecounter; + + if (!isset($record['fullname'])) { + $record['fullname'] = 'Grade outcome ' . $i; + } + + // For gradelib classes. + require_once($CFG->libdir . '/gradelib.php'); + // Create new grading outcome in this course. + $gradeoutcome = new grade_outcome($record, false); + $gradeoutcome->insert(); + + $gradeoutcome->update_from_db(); + return $gradeoutcome->get_record_data(); + } } diff --git a/lib/tests/behat/behat_data_generators.php b/lib/tests/behat/behat_data_generators.php index 2ce1a86596d..3a957dc8a05 100644 --- a/lib/tests/behat/behat_data_generators.php +++ b/lib/tests/behat/behat_data_generators.php @@ -140,6 +140,22 @@ class behat_data_generators extends behat_base { 'datagenerator' => 'grade_category', 'required' => array('fullname', 'course'), 'switchids' => array('course' => 'courseid', 'gradecategory' => 'parent') + ), + 'grade items' => array( + 'datagenerator' => 'grade_item', + 'required' => array('course'), + 'switchids' => array('scale' => 'scaleid', 'outcome' => 'outcomeid', 'course' => 'courseid', + 'gradecategory' => 'categoryid') + ), + 'grade outcomes' => array( + 'datagenerator' => 'grade_outcome', + 'required' => array('shortname', 'scale'), + 'switchids' => array('course' => 'courseid', 'gradecategory' => 'categoryid', 'scale' => 'scaleid') + ), + 'scales' => array( + 'datagenerator' => 'scale', + 'required' => array('name', 'scale'), + 'switchids' => array('course' => 'courseid') ) ); @@ -246,6 +262,21 @@ class behat_data_generators extends behat_base { return $data; } + /** + * Preprocesses the creation of a grade item. Converts gradetype text to a number. + * @param array $data + * @return array + */ + protected function preprocess_grade_item($data) { + global $CFG; + require_once("$CFG->libdir/grade/constants.php"); + + if (isset($data['gradetype'])) { + $data['gradetype'] = constant("GRADE_TYPE_" . strtoupper($data['gradetype'])); + } + return $data; + } + /** * Adapter to modules generator * @throws Exception Custom exception for test writers @@ -253,12 +284,22 @@ class behat_data_generators extends behat_base { * @return void */ protected function process_activity($data) { - global $DB; + global $DB, $CFG; // The the_following_exists() method checks that the field exists. $activityname = $data['activity']; unset($data['activity']); + // Convert scale name into scale id (negative number indicates using scale). + if (isset($data['grade']) && strlen($data['grade']) && !is_number($data['grade'])) { + $data['grade'] = - $this->get_scale_id($data['grade']); + require_once("$CFG->libdir/grade/constants.php"); + + if (!isset($data['gradetype'])) { + $data['gradetype'] = GRADE_TYPE_SCALE; + } + } + // We split $data in the activity $record and the course module $options. $cmoptions = array(); $cmcolumns = $DB->get_columns('course_modules'); @@ -559,6 +600,36 @@ class behat_data_generators extends behat_base { return $id; } + /** + * Gets the outcome item id from its shortname. + * @throws Exception + * @param string $shortname + * @return int + */ + protected function get_outcome_id($shortname) { + global $DB; + + if (!$id = $DB->get_field('grade_outcomes', 'id', array('shortname' => $shortname))) { + throw new Exception('The specified outcome with shortname "' . $shortname . '" does not exist'); + } + return $id; + } + + /** + * Gets the course id from its name. + * @throws Exception + * @param string $name + * @return int + */ + protected function get_scale_id($name) { + global $DB; + + if (!$id = $DB->get_field('scale', 'id', array('name' => $name))) { + throw new Exception('The specified scale with name "' . $name . '" does not exist'); + } + return $id; + } + /** * Gets the internal context id from the context reference. *