From 002ccdcf49201dab3c25c42ed2807baa6c64cdf1 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Mon, 1 Sep 2014 13:35:54 +0100 Subject: [PATCH] MDL-44725 Add Behat support for setting grouping condition (14) Makes it possible to add a grouping condition when creating an activity, using the Behat field type API. You can set the field using a syntax 'Grouping: NAME' (at present, only groupings are supported, obviously we could potentially extend this to add support for other conditions if needed). Tested in Firefox and Chrome in JS mode, and in non-JS mode. --- .../tests/behat/structural_changes.feature | 42 +++---- lib/behat/behat_field_manager.php | 5 + .../form_field/behat_form_availability.php | 117 ++++++++++++++++++ 3 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 lib/behat/form_field/behat_form_availability.php diff --git a/blocks/recent_activity/tests/behat/structural_changes.feature b/blocks/recent_activity/tests/behat/structural_changes.feature index 31911e3a816..78814a59fe7 100644 --- a/blocks/recent_activity/tests/behat/structural_changes.feature +++ b/blocks/recent_activity/tests/behat/structural_changes.feature @@ -48,7 +48,7 @@ Feature: View structural changes in recent activity block Scenario: Check that Added module information is displayed respecting view capability Given I log in as "admin" And I set the following administration settings values: - | Enable group members only | 1 | + | Enable conditional access | 1 | And I log out And I log in as "teacher1" And I follow "Course 1" @@ -70,29 +70,29 @@ Feature: View structural changes in recent activity block | Description | No description | | groupmode | No groups | And I add a "Forum" to section "2" and I fill the form with: - | name | ForumVisibleGroupsG1 | - | Description | No description | - | groupmode | Visible groups | - | Grouping | Grouping 1 | - | Available for group members only | 1 | + | name | ForumVisibleGroupsG1 | + | Description | No description | + | groupmode | Visible groups | + | Grouping | Grouping 1 | + | Access restrictions | Grouping: Grouping 1 | And I add a "Forum" to section "2" and I fill the form with: - | name | ForumSeparateGroupsG1 | - | Description | No description | - | groupmode | Separate groups | - | Grouping | Grouping 1 | - | Available for group members only | 1 | + | name | ForumSeparateGroupsG1 | + | Description | No description | + | groupmode | Separate groups | + | Grouping | Grouping 1 | + | Access restrictions | Grouping: Grouping 1 | And I add a "Forum" to section "3" and I fill the form with: - | name | ForumVisibleGroupsG2 | - | Description | No description | - | groupmode | Visible groups | - | Grouping | Grouping 2 | - | Available for group members only | 1 | + | name | ForumVisibleGroupsG2 | + | Description | No description | + | groupmode | Visible groups | + | Grouping | Grouping 2 | + | Access restrictions | Grouping: Grouping 2 | And I add a "Forum" to section "3" and I fill the form with: - | name | ForumSeparateGroupsG2 | - | Description | No description | - | groupmode | Separate groups | - | Grouping | Grouping 2 | - | Available for group members only | 1 | + | name | ForumSeparateGroupsG2 | + | Description | No description | + | groupmode | Separate groups | + | Grouping | Grouping 2 | + | Access restrictions | Grouping: Grouping 2 | Then I should see "ForumVisibleGroups" in the "Recent activity" "block" And I should see "ForumSeparateGroups" in the "Recent activity" "block" And I should see "ForumNoGroups" in the "Recent activity" "block" diff --git a/lib/behat/behat_field_manager.php b/lib/behat/behat_field_manager.php index dd22b0bbab6..9bac774bed3 100644 --- a/lib/behat/behat_field_manager.php +++ b/lib/behat/behat_field_manager.php @@ -218,6 +218,11 @@ class behat_field_manager { */ protected static function get_field_node_type(NodeElement $fieldnode, Session $session) { + // Special handling for availability field which requires custom JavaScript. + if ($fieldnode->getAttribute('name') === 'availabilityconditionsjson') { + return 'availability'; + } + // We look for a parent node with 'felement' class. if ($class = $fieldnode->getParent()->getAttribute('class')) { diff --git a/lib/behat/form_field/behat_form_availability.php b/lib/behat/form_field/behat_form_availability.php new file mode 100644 index 00000000000..23fac461c75 --- /dev/null +++ b/lib/behat/form_field/behat_form_availability.php @@ -0,0 +1,117 @@ +. + +/** + * Availability form field class. + * + * @package core_form + * @category test + * @copyright 2014 The Open 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__ . '/behat_form_field.php'); + +/** + * Availability form field class. + * + * @package core_form + * @category test + * @copyright 2014 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_form_availability extends behat_form_textarea { + + /** + * Sets the value(s) of an availability element. + * + * At present this only supports the following value 'Grouping: xxx' where + * xxx is the name of a grouping. Additional value types can be added as + * necessary. + * + * @param string $value Value code + * @return void + */ + public function set_value($value) { + global $DB; + $driver = $this->session->getDriver(); + + // Check the availability condition is currently unset - we don't yet + // support changing an existing one. + $existing = $this->get_value(); + if ($existing && $existing !== '{"op":"&","c":[],"showc":[]}') { + throw new Exception('Cannot automatically set availability when ' . + 'there is existing setting - must clear manually'); + } + + // Check the value matches a supported format. + $matches = array(); + if (!preg_match('~^\s*([^:]*):\s*(.*?)\s*$~', $value, $matches)) { + throw new Exception('Value for availability field does not match correct ' . + 'format. Example: "Grouping: G1"'); + } + $type = $matches[1]; + $param = $matches[2]; + + if ($this->running_javascript()) { + switch (strtolower($type)) { + case 'grouping' : + // Set a grouping condition. + $driver->click('//div[@class="availability-button"]/button'); + $driver->click('//button[@id="availability_addrestriction_grouping"]'); + $escparam = $this->session->getSelectorsHandler()->xpathLiteral($param); + $nodes = $driver->find( + '//span[contains(concat(" " , @class, " "), " availability_grouping ")]//' . + 'option[normalize-space(.) = ' . $escparam . ']'); + if (count($nodes) != 1) { + throw new Exception('Cannot find grouping in dropdown' . count($nodes)); + } + $node = reset($nodes); + $value = $node->getValue(); + $driver->selectOption( + '//span[contains(concat(" " , @class, " "), " availability_grouping ")]//' . + 'select', $value); + break; + + default: + // We don't support other types yet. The test author must write + // manual 'click on that button, etc' commands. + throw new Exception('The availability type "' . $type . + '" is currently not supported - must set manually'); + } + } else { + $courseid = $driver->getValue('//input[@name="course"]'); + switch (strtolower($type)) { + case 'grouping' : + // Define result with one grouping condition. + $groupingid = $DB->get_field('groupings', 'id', + array('courseid' => $courseid, 'name' => $param)); + $json = \core_availability\tree::get_root_json(array( + \availability_grouping\condition::get_json($groupingid))); + break; + + default: + // We don't support other types yet. + throw new Exception('The availability type "' . $type . + '" is currently not supported - must set with JavaScript'); + } + $driver->setValue('//textarea[@name="availabilityconditionsjson"]', + json_encode($json)); + } + } +}