1 |
efrain |
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/>.
|
|
|
16 |
|
|
|
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 |
*/
|
|
|
25 |
|
|
|
26 |
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
|
|
27 |
|
|
|
28 |
require_once(__DIR__ . '/../../behat/behat_base.php');
|
|
|
29 |
|
|
|
30 |
use Behat\Mink\Exception\ExpectationException as ExpectationException,
|
|
|
31 |
Behat\Gherkin\Node\TableNode as TableNode;
|
|
|
32 |
|
|
|
33 |
/**
|
|
|
34 |
* Steps definitions to set up permissions to capabilities.
|
|
|
35 |
*
|
|
|
36 |
* @package core
|
|
|
37 |
* @category test
|
|
|
38 |
* @copyright 2013 David Monllaó
|
|
|
39 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
40 |
*/
|
|
|
41 |
class behat_permissions extends behat_base {
|
|
|
42 |
|
|
|
43 |
/**
|
|
|
44 |
* Set system level permissions to the specified role. Expects a table with capability name and permission (Inherit/Allow/Prevent/Prohibit) columns.
|
|
|
45 |
* @Given /^I set the following system permissions of "(?P<rolefullname_string>(?:[^"]|\\")*)" role:$/
|
|
|
46 |
* @param string $rolename
|
|
|
47 |
* @param TableNode $table
|
|
|
48 |
*/
|
|
|
49 |
public function i_set_the_following_system_permissions_of_role($rolename, $table) {
|
|
|
50 |
// Applied in the System context.
|
|
|
51 |
$context = \context_system::instance();
|
|
|
52 |
|
|
|
53 |
// Translate the specified rolename into a role.
|
|
|
54 |
$rolenames = role_get_names($context);
|
|
|
55 |
$matched = array_filter($rolenames, function($role) use ($rolename) {
|
|
|
56 |
return ($role->localname === $rolename) || ($role->shortname === $rolename) || ($role->description === $rolename);
|
|
|
57 |
});
|
|
|
58 |
|
|
|
59 |
if (count($matched) === 0) {
|
|
|
60 |
throw new ExpectationException("Unable to find a role with name '{$rolename}'", $this->getSession());
|
|
|
61 |
} else if (count($matched) > 1) {
|
|
|
62 |
throw new ExpectationException("Multiple roles matched '{$rolename}'", $this->getSession());
|
|
|
63 |
}
|
|
|
64 |
|
|
|
65 |
$role = reset($matched);
|
|
|
66 |
|
|
|
67 |
$permissionmap = [
|
|
|
68 |
get_string('inherit', 'role') => 'inherit',
|
|
|
69 |
get_string('allow', 'role') => 'allow',
|
|
|
70 |
get_string('prevent', 'role') => 'prevent',
|
|
|
71 |
get_string('prohibit', 'role') => 'prohibit',
|
|
|
72 |
];
|
|
|
73 |
|
|
|
74 |
$columns = ['role'];
|
|
|
75 |
$newtabledata = [$role->shortname];
|
|
|
76 |
foreach ($table as $data) {
|
|
|
77 |
$columns[] = $data['capability'];
|
|
|
78 |
$newtabledata[] = $permissionmap[$data['permission']];
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
$this->execute(
|
|
|
82 |
'behat_data_generators::the_following_entities_exist',
|
|
|
83 |
[
|
|
|
84 |
'role capabilities',
|
|
|
85 |
new TableNode([
|
|
|
86 |
|
|
|
87 |
1 => $newtabledata,
|
|
|
88 |
])
|
|
|
89 |
]
|
|
|
90 |
);
|
|
|
91 |
}
|
|
|
92 |
|
|
|
93 |
/**
|
|
|
94 |
* 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.
|
|
|
95 |
* @Given /^I override the system permissions of "(?P<rolefullname_string>(?:[^"]|\\")*)" role with:$/
|
|
|
96 |
* @param string $rolename
|
|
|
97 |
* @param TableNode $table
|
|
|
98 |
*/
|
|
|
99 |
public function i_override_the_system_permissions_of_role_with($rolename, $table) {
|
|
|
100 |
|
|
|
101 |
// We don't know the number of overrides so we have to get it to match the option contents.
|
|
|
102 |
$roleoption = $this->find('xpath', '//select[@name="roleid"]/option[contains(.,"' . $this->escape($rolename) . '")]');
|
|
|
103 |
|
|
|
104 |
$this->execute('behat_forms::i_set_the_field_to',
|
|
|
105 |
array(get_string('advancedoverride', 'role'), $this->escape($roleoption->getText()))
|
|
|
106 |
);
|
|
|
107 |
|
|
|
108 |
if (!$this->running_javascript()) {
|
|
|
109 |
$xpath = "//div[@class='advancedoverride']/div/form/noscript";
|
|
|
110 |
$this->execute("behat_general::i_click_on_in_the", [
|
|
|
111 |
get_string('go'), 'button',
|
|
|
112 |
$this->escape($xpath),
|
|
|
113 |
'xpath_element']
|
|
|
114 |
);
|
|
|
115 |
}
|
|
|
116 |
|
|
|
117 |
$this->execute("behat_permissions::i_fill_the_capabilities_form_with_the_following_permissions", $table);
|
|
|
118 |
|
|
|
119 |
$this->execute('behat_forms::press_button', get_string('savechanges'));
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
/**
|
|
|
123 |
* Fills the advanced permissions form with the provided data. Expects a table with capability name and permission (Inherit/Allow/Prevent/Prohibit) columns.
|
|
|
124 |
* @Given /^I fill the capabilities form with the following permissions:$/
|
|
|
125 |
* @param TableNode $table
|
|
|
126 |
* @return void
|
|
|
127 |
*/
|
|
|
128 |
public function i_fill_the_capabilities_form_with_the_following_permissions($table) {
|
|
|
129 |
|
|
|
130 |
// Ensure we are using the advanced view.
|
|
|
131 |
// Wrapped in a try/catch to capture the exception and continue execution, we don't know if advanced mode was already enabled.
|
|
|
132 |
try {
|
|
|
133 |
$advancedtoggle = $this->find_button(get_string('showadvanced', 'form'));
|
|
|
134 |
if ($advancedtoggle) {
|
|
|
135 |
$advancedtoggle->click();
|
|
|
136 |
|
|
|
137 |
// Wait for the page to load.
|
|
|
138 |
$this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS);
|
|
|
139 |
}
|
|
|
140 |
} catch (Exception $e) {
|
|
|
141 |
// We already are in advanced mode.
|
|
|
142 |
}
|
|
|
143 |
|
|
|
144 |
// Using getRows() as we are not sure if tests writers will add the header.
|
|
|
145 |
foreach ($table->getRows() as $key => $row) {
|
|
|
146 |
|
|
|
147 |
if (count($row) !== 2) {
|
|
|
148 |
throw new ExpectationException('You should specify a table with capability/permission columns', $this->getSession());
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
list($capability, $permission) = $row;
|
|
|
152 |
|
|
|
153 |
// Skip the headers row if it was provided
|
|
|
154 |
if (strtolower($capability) == 'capability' || strtolower($capability) == 'capabilities') {
|
|
|
155 |
continue;
|
|
|
156 |
}
|
|
|
157 |
|
|
|
158 |
// Checking the permission value.
|
|
|
159 |
$permissionconstant = 'CAP_'. strtoupper($permission);
|
|
|
160 |
if (!defined($permissionconstant)) {
|
|
|
161 |
throw new ExpectationException(
|
|
|
162 |
'The provided permission value "' . $permission . '" is not valid. Use Inherit, Allow, Prevent or Prohibited',
|
|
|
163 |
$this->getSession()
|
|
|
164 |
);
|
|
|
165 |
}
|
|
|
166 |
|
|
|
167 |
// Converting from permission to constant value.
|
|
|
168 |
$permissionvalue = constant($permissionconstant);
|
|
|
169 |
|
|
|
170 |
// Here we wait for the element to appear and exception if it does not exist.
|
|
|
171 |
$radio = $this->find('xpath', '//input[@name="' . $capability . '" and @value="' . $permissionvalue . '"]');
|
|
|
172 |
$field = behat_field_manager::get_field_instance('radio', $radio, $this->getSession());
|
|
|
173 |
$field->set_value(1);
|
|
|
174 |
}
|
|
|
175 |
}
|
|
|
176 |
|
|
|
177 |
/**
|
|
|
178 |
* Checks if the capability has the specified permission. Works in the role definition advanced page.
|
|
|
179 |
*
|
|
|
180 |
* @Then /^"(?P<capability_string>(?:[^"]|\\")*)" capability has "(?P<permission_string>Not set|Allow|Prevent|Prohibit)" permission$/
|
|
|
181 |
* @throws ExpectationException
|
|
|
182 |
* @param string $capabilityname
|
|
|
183 |
* @param string $permission
|
|
|
184 |
* @return void
|
|
|
185 |
*/
|
|
|
186 |
public function capability_has_permission($capabilityname, $permission) {
|
|
|
187 |
|
|
|
188 |
// We already know the name, so we just need the value.
|
|
|
189 |
$radioxpath = "//table[contains(concat(' ',
|
|
|
190 |
normalize-space(@class), ' '), ' rolecap ')]/descendant::input[@type='radio']" .
|
|
|
191 |
"[@name='" . $capabilityname . "'][@checked]";
|
|
|
192 |
|
|
|
193 |
$checkedradio = $this->find('xpath', $radioxpath);
|
|
|
194 |
|
|
|
195 |
switch ($permission) {
|
|
|
196 |
case get_string('notset', 'role'):
|
|
|
197 |
$perm = CAP_INHERIT;
|
|
|
198 |
break;
|
|
|
199 |
case get_string('allow', 'role'):
|
|
|
200 |
$perm = CAP_ALLOW;
|
|
|
201 |
break;
|
|
|
202 |
case get_string('prevent', 'role'):
|
|
|
203 |
$perm = CAP_PREVENT;
|
|
|
204 |
break;
|
|
|
205 |
case get_string('prohibit', 'role'):
|
|
|
206 |
$perm = CAP_PROHIBIT;
|
|
|
207 |
break;
|
|
|
208 |
default:
|
|
|
209 |
throw new ExpectationException('"' . $permission . '" permission does not exist', $this->getSession());
|
|
|
210 |
break;
|
|
|
211 |
}
|
|
|
212 |
|
|
|
213 |
if ($checkedradio->getAttribute('value') != $perm) {
|
|
|
214 |
throw new ExpectationException('"' . $capabilityname . '" permission is not "' . $permission . '"', $this->getSession());
|
|
|
215 |
}
|
|
|
216 |
}
|
|
|
217 |
|
|
|
218 |
/**
|
|
|
219 |
* Set the allowed role assignments for the specified role.
|
|
|
220 |
*
|
|
|
221 |
* @Given /^I define the allowed role assignments for the "(?P<rolefullname_string>(?:[^"]|\\")*)" role as:$/
|
|
|
222 |
* @param string $rolename
|
|
|
223 |
* @param TableNode $table
|
|
|
224 |
* @return void Executes other steps
|
|
|
225 |
*/
|
|
|
226 |
public function i_define_the_allowed_role_assignments_for_a_role_as($rolename, $table) {
|
|
|
227 |
$parentnodes = get_string('users', 'admin') . ' > ' .
|
|
|
228 |
get_string('permissions', 'role');
|
|
|
229 |
|
|
|
230 |
// Go to home page.
|
|
|
231 |
$this->execute("behat_general::i_am_on_homepage");
|
|
|
232 |
|
|
|
233 |
// Navigate to Define roles page via site administration menu.
|
|
|
234 |
$this->execute("behat_navigation::i_navigate_to_in_site_administration",
|
|
|
235 |
$parentnodes .' > '. get_string('defineroles', 'role')
|
|
|
236 |
);
|
|
|
237 |
|
|
|
238 |
$this->execute("behat_general::click_link", "Allow role assignments");
|
|
|
239 |
$this->execute("behat_permissions::i_fill_in_the_allowed_role_assignments_form_for_a_role_with",
|
|
|
240 |
array($rolename, $table)
|
|
|
241 |
);
|
|
|
242 |
|
|
|
243 |
$this->execute('behat_forms::press_button', get_string('savechanges'));
|
|
|
244 |
}
|
|
|
245 |
|
|
|
246 |
/**
|
|
|
247 |
* Fill in the allowed role assignments form for the specied role.
|
|
|
248 |
*
|
|
|
249 |
* Takes a table with two columns. Each row should contain the target
|
|
|
250 |
* role, and either "Assignable" or "Not assignable".
|
|
|
251 |
*
|
|
|
252 |
* @Given /^I fill in the allowed role assignments form for the "(?P<rolefullname_string>(?:[^"]|\\")*)" role with:$/
|
|
|
253 |
* @param String $sourcerole
|
|
|
254 |
* @param TableNode $table
|
|
|
255 |
* @return void
|
|
|
256 |
*/
|
|
|
257 |
public function i_fill_in_the_allowed_role_assignments_form_for_a_role_with($sourcerole, $table) {
|
|
|
258 |
foreach ($table->getRows() as $key => $row) {
|
|
|
259 |
list($targetrole, $allowed) = $row;
|
|
|
260 |
|
|
|
261 |
$node = $this->find('xpath', '//input[@title="Allow users with role ' .
|
|
|
262 |
$sourcerole .
|
|
|
263 |
' to assign the role ' .
|
|
|
264 |
$targetrole . '"]');
|
|
|
265 |
|
|
|
266 |
if ($allowed == 'Assignable') {
|
|
|
267 |
if (!$node->isChecked()) {
|
|
|
268 |
$node->check();
|
|
|
269 |
}
|
|
|
270 |
} else if ($allowed == 'Not assignable') {
|
|
|
271 |
if ($node->isChecked()) {
|
|
|
272 |
$node->uncheck();
|
|
|
273 |
}
|
|
|
274 |
} else {
|
|
|
275 |
throw new ExpectationException(
|
|
|
276 |
'The provided permission value "' . $allowed . '" is not valid. Use Assignable, or Not assignable',
|
|
|
277 |
$this->getSession()
|
|
|
278 |
);
|
|
|
279 |
}
|
|
|
280 |
}
|
|
|
281 |
}
|
|
|
282 |
|
|
|
283 |
/**
|
|
|
284 |
* Mark context as frozen.
|
|
|
285 |
*
|
|
|
286 |
* @Then /^the "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)" is context frozen$/
|
|
|
287 |
* @throws ExpectationException if the context cannot be frozen or found
|
|
|
288 |
* @param string $element Element we look on
|
|
|
289 |
* @param string $selector The type of where we look (activity, course)
|
|
|
290 |
*/
|
|
|
291 |
public function the_context_is_context_frozen(string $element, string $selector) {
|
|
|
292 |
|
|
|
293 |
// Enable context freeze if it is not done yet.
|
|
|
294 |
set_config('contextlocking', 1);
|
|
|
295 |
|
|
|
296 |
// Find context.
|
|
|
297 |
$context = self::get_context($selector, $element);
|
|
|
298 |
|
|
|
299 |
// Freeze context.
|
|
|
300 |
$context->set_locked(true);
|
|
|
301 |
}
|
|
|
302 |
|
|
|
303 |
/**
|
|
|
304 |
* Unmark context as frozen.
|
|
|
305 |
*
|
|
|
306 |
* @Then /^the "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)" is not context frozen$/
|
|
|
307 |
* @throws ExpectationException if the context cannot be frozen or found
|
|
|
308 |
* @param string $element Element we look on
|
|
|
309 |
* @param string $selector The type of where we look (activity, course)
|
|
|
310 |
*/
|
|
|
311 |
public function the_context_is_not_context_frozen(string $element, string $selector) {
|
|
|
312 |
|
|
|
313 |
// Enable context freeze if it is not done yet.
|
|
|
314 |
set_config('contextlocking', 1);
|
|
|
315 |
|
|
|
316 |
// Find context.
|
|
|
317 |
$context = self::get_context($selector, $element);
|
|
|
318 |
|
|
|
319 |
// Freeze context.
|
|
|
320 |
$context->set_locked(false);
|
|
|
321 |
}
|
|
|
322 |
}
|