MDL-50163 behat: Return subcontext from session
[moodle.git] / lib / tests / behat / behat_permissions.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Steps definitions related with permissions.
19  *
20  * @package   core
21  * @category  test
22  * @copyright 2013 David MonllaĆ³
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
28 require_once(__DIR__ . '/../../behat/behat_base.php');
30 use Behat\Mink\Exception\ExpectationException as ExpectationException,
31     Behat\Behat\Context\Step\Given as Given,
32     Behat\Gherkin\Node\TableNode as TableNode;
34 /**
35  * Steps definitions to set up permissions to capabilities.
36  *
37  * @package   core
38  * @category  test
39  * @copyright 2013 David MonllaĆ³
40  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  */
42 class behat_permissions extends behat_base {
44     /**
45      * Set system level permissions to the specified role. Expects a table with capability name and permission (Inherit/Allow/Prevent/Prohibit) columns.
46      * @Given /^I set the following system permissions of "(?P<rolefullname_string>(?:[^"]|\\")*)" role:$/
47      * @param string $rolename
48      * @param TableNode $table
49      * @return void Executes other steps
50      */
51     public function i_set_the_following_system_permissions_of_role($rolename, $table) {
53         $parentnodes = get_string('administrationsite') . ' > ' .
54             get_string('users', 'admin') . ' > ' .
55             get_string('permissions', 'role');
56         return array(
57             new Given('I am on homepage'),
58             new Given('I navigate to "' . get_string('defineroles', 'role') . '" node in "' . $parentnodes . '"'),
59             new Given('I follow "Edit ' . $this->escape($rolename) . ' role"'),
60             new Given('I fill the capabilities form with the following permissions:', $table),
61             new Given('I press "' . get_string('savechanges') . '"')
62         );
63     }
65     /**
66      * Overrides system capabilities at category, course and module levels. This step begins after clicking 'Permissions' link. Expects a table with capability name and permission (Inherit/Allow/Prevent/Prohibit) columns.
67      * @Given /^I override the system permissions of "(?P<rolefullname_string>(?:[^"]|\\")*)" role with:$/
68      * @param string $rolename
69      * @param TableNode $table
70      * @return void Executes other steps
71      */
72     public function i_override_the_system_permissions_of_role_with($rolename, $table) {
74         // We don't know the number of overrides so we have to get it to match the option contents.
75         $roleoption = $this->find('xpath', '//select[@name="roleid"]/option[contains(.,"' . $this->escape($rolename) . '")]');
77         $result = array(
78             new Given('I set the field "' . get_string('advancedoverride', 'role') .
79                 '" to "' . $this->escape($roleoption->getText()) . '"'));
80         if (!$this->running_javascript()) {
81             $result[] = new Given('I press "' . get_string('go') . '"');
82         }
83         $result[] = new Given('I fill the capabilities form with the following permissions:', $table);
84         $result[] = new Given('I press "' . get_string('savechanges') . '"');
85         return $result;
86     }
88     /**
89      * Fills the advanced permissions form with the provided data. Expects a table with capability name and permission (Inherit/Allow/Prevent/Prohibit) columns.
90      * @Given /^I fill the capabilities form with the following permissions:$/
91      * @param TableNode $table
92      * @return void
93      */
94     public function i_fill_the_capabilities_form_with_the_following_permissions($table) {
96         // Ensure we are using the advanced view.
97         // Wrapped in a try/catch to capture the exception and continue execution, we don't know if advanced mode was already enabled.
98         try {
99             $advancedtoggle = $this->find_button(get_string('showadvanced', 'form'));
100             if ($advancedtoggle) {
101                 $advancedtoggle->click();
103                 // Wait for the page to load.
104                 $this->getSession()->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
105             }
106         } catch (Exception $e) {
107             // We already are in advanced mode.
108         }
110         // Using getRows() as we are not sure if tests writers will add the header.
111         foreach ($table->getRows() as $key => $row) {
113             if (count($row) !== 2) {
114                 throw new ExpectationException('You should specify a table with capability/permission columns', $this->getSession());
115             }
117             list($capability, $permission) = $row;
119             // Skip the headers row if it was provided
120             if (strtolower($capability) == 'capability' || strtolower($capability) == 'capabilities') {
121                 continue;
122             }
124             // Checking the permission value.
125             $permissionconstant = 'CAP_'. strtoupper($permission);
126             if (!defined($permissionconstant)) {
127                 throw new ExpectationException(
128                     'The provided permission value "' . $permission . '" is not valid. Use Inherit, Allow, Prevent or Prohibited',
129                     $this->getSession()
130                 );
131             }
133             // Converting from permission to constant value.
134             $permissionvalue = constant($permissionconstant);
136             // Here we wait for the element to appear and exception if it does not exist.
137             $radio = $this->find('xpath', '//input[@name="' . $capability . '" and @value="' . $permissionvalue . '"]');
138             $field = behat_field_manager::get_field_instance('radio', $radio, $this->getSession());
139             $field->set_value(1);
140         }
141     }
143     /**
144      * Checks if the capability has the specified permission. Works in the role definition advanced page.
145      *
146      * @Then /^"(?P<capability_string>(?:[^"]|\\")*)" capability has "(?P<permission_string>Not set|Allow|Prevent|Prohibit)" permission$/
147      * @throws ExpectationException
148      * @param string $capabilityname
149      * @param string $permission
150      * @return void
151      */
152     public function capability_has_permission($capabilityname, $permission) {
154         // We already know the name, so we just need the value.
155         $radioxpath = "//table[@class='rolecap']/descendant::input[@type='radio']" .
156             "[@name='" . $capabilityname . "'][@checked]";
158         $checkedradio = $this->find('xpath', $radioxpath);
160         switch ($permission) {
161             case get_string('notset', 'role'):
162                 $perm = CAP_INHERIT;
163                 break;
164             case get_string('allow', 'role'):
165                 $perm = CAP_ALLOW;
166                 break;
167             case get_string('prevent', 'role'):
168                 $perm = CAP_PREVENT;
169                 break;
170             case get_string('prohibit', 'role'):
171                 $perm = CAP_PROHIBIT;
172                 break;
173             default:
174                 throw new ExpectationException('"' . $permission . '" permission does not exist', $this->getSession());
175                 break;
176         }
178         if ($checkedradio->getAttribute('value') != $perm) {
179             throw new ExpectationException('"' . $capabilityname . '" permission is not "' . $permission . '"', $this->getSession());
180         }
181     }
183     /**
184      * Set the allowed role assignments for the specified role.
185      *
186      * @Given /^I define the allowed role assignments for the "(?P<rolefullname_string>(?:[^"]|\\")*)" role as:$/
187      * @param string $rolename
188      * @param TableNode $table
189      * @return void Executes other steps
190      */
191     public function i_define_the_allowed_role_assignments_for_a_role_as($rolename, $table) {
192         $parentnodes = get_string('administrationsite') . ' > ' .
193             get_string('users', 'admin') . ' > ' .
194             get_string('permissions', 'role');
195         return array(
196             new Given('I am on homepage'),
197             new Given('I navigate to "' . get_string('defineroles', 'role') . '" node in "' . $parentnodes . '"'),
198             new Given('I follow "Allow role assignments"'),
199             new Given('I fill in the allowed role assignments form for the "' . $rolename . '" role with:', $table),
200             new Given('I press "' . get_string('savechanges') . '"')
201         );
202     }
204     /**
205      * Fill in the allowed role assignments form for the specied role.
206      *
207      * Takes a table with two columns. Each row should contain the target
208      * role, and either "Assignable" or "Not assignable".
209      *
210      * @Given /^I fill in the allowed role assignments form for the "(?P<rolefullname_string>(?:[^"]|\\")*)" role with:$/
211      * @param String $sourcerole
212      * @param TableNode $table
213      * @return void
214      */
215     public function i_fill_in_the_allowed_role_assignments_form_for_a_role_with($sourcerole, $table) {
216         foreach ($table->getRows() as $key => $row) {
217             list($targetrole, $allowed) = $row;
219             $node = $this->find('xpath', '//input[@title="Allow users with role ' .
220                 $sourcerole .
221                 ' to assign the role ' .
222                 $targetrole . '"]');
224             if ($allowed == 'Assignable') {
225                 if (!$node->isChecked()) {
226                     $node->click();
227                 }
228             } else if ($allowed == 'Not assignable') {
229                 if ($node->isChecked()) {
230                     $node->click();
231                 }
232             } else {
233                 throw new ExpectationException(
234                     'The provided permission value "' . $allowed . '" is not valid. Use Assignable, or Not assignable',
235                     $this->getSession()
236                 );
237             }
238         }
239     }