MDL-81601 core_course: Add course index completion status behats
[moodle.git] / reportbuilder / tests / permission_test.php
blobf0806880b89e28988611191bf7b7b084af201cd3
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.
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 declare(strict_types=1);
19 namespace core_reportbuilder;
21 use advanced_testcase;
22 use context_system;
23 use core_reportbuilder_generator;
24 use Throwable;
25 use core_user\reportbuilder\datasource\users;
26 use core_reportbuilder\reportbuilder\audience\manual;
28 /**
29 * Unit tests for the report permission class
31 * @package core_reportbuilder
32 * @covers \core_reportbuilder\permission
33 * @copyright 2021 Paul Holden <paulh@moodle.com>
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 class permission_test extends advanced_testcase {
38 /**
39 * Test whether user can view reports list
41 public function test_require_can_view_reports_list(): void {
42 global $DB;
44 $this->resetAfterTest();
46 // User with default permission.
47 $user = $this->getDataGenerator()->create_user();
48 $this->setUser($user);
50 try {
51 permission::require_can_view_reports_list();
52 } catch (Throwable $exception) {
53 $this->fail($exception->getMessage());
56 // User without permission.
57 $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
58 unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
60 $this->expectException(report_access_exception::class);
61 $this->expectExceptionMessage('You cannot view this report');
62 permission::require_can_view_reports_list();
65 /**
66 * Data provider for {@see test_require_can_view_reports_list_with_capability}
68 * @return array[]
70 public static function require_can_view_reports_list_with_capability_provider(): array {
71 return [
72 ['moodle/reportbuilder:edit'],
73 ['moodle/reportbuilder:editall'],
74 ['moodle/reportbuilder:viewall'],
78 /**
79 * Test that viewing reports list observes capability to do so
81 * @param string $capability
83 * @dataProvider require_can_view_reports_list_with_capability_provider
85 public function test_require_can_view_reports_list_with_capability(string $capability): void {
86 global $DB;
88 $this->resetAfterTest();
90 $user = $this->getDataGenerator()->create_user();
91 $this->setUser($user);
93 $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
95 // Remove default capability, allow additional.
96 unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
97 assign_capability($capability, CAP_ALLOW, $userrole, context_system::instance());
99 try {
100 permission::require_can_view_reports_list();
101 } catch (Throwable $exception) {
102 $this->fail($exception->getMessage());
107 * Test whether user can view reports list when custom reports are disabled
109 public function test_require_can_view_reports_list_disabled(): void {
110 $this->resetAfterTest();
111 $this->setAdminUser();
113 set_config('enablecustomreports', 0);
115 $this->expectException(report_access_exception::class);
116 $this->expectExceptionMessage('You cannot view this report');
117 permission::require_can_view_reports_list();
121 * Test whether user can view specific report
123 public function test_require_can_view_report(): void {
124 $this->resetAfterTest();
126 /** @var core_reportbuilder_generator $generator */
127 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
128 $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
130 // User with permission.
131 $this->setAdminUser();
132 try {
133 permission::require_can_view_report($report);
134 } catch (Throwable $exception) {
135 $this->fail($exception->getMessage());
138 // User without permission.
139 $user = $this->getDataGenerator()->create_user();
140 $this->setUser($user);
142 $this->expectException(report_access_exception::class);
143 $this->expectExceptionMessage('You cannot view this report');
144 permission::require_can_view_report($report);
148 * Data provider for {@see test_require_can_view_report_with_capability}
150 * @return array[]
152 public static function require_can_view_report_with_capability_provider(): array {
153 return [
154 ['moodle/reportbuilder:editall'],
155 ['moodle/reportbuilder:viewall'],
160 * Test whether user can view specific report when they have capability to view all reports
162 * @param string $capability
164 * @dataProvider require_can_view_report_with_capability_provider
166 public function test_require_can_view_report_with_capability(string $capability): void {
167 global $DB;
169 $this->resetAfterTest();
171 // Admin creates a report, no audience.
172 $this->setAdminUser();
174 /** @var core_reportbuilder_generator $generator */
175 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
176 $report = $generator->create_report(['name' => 'Admin report', 'source' => users::class]);
178 // Switch to new user, assign capability.
179 $user = $this->getDataGenerator()->create_user();
180 $this->setUser($user);
182 $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
183 assign_capability($capability, CAP_ALLOW, $userrole, context_system::instance());
185 try {
186 permission::require_can_view_report($report);
187 } catch (Throwable $exception) {
188 $this->fail($exception->getMessage());
193 * Test whether user can view specific report when it belongs to an audience
195 public function test_require_can_view_report_with_audience(): void {
196 global $DB;
198 $this->resetAfterTest();
200 /** @var core_reportbuilder_generator $generator */
201 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
202 $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
204 // User without permission.
205 $user = $this->getDataGenerator()->create_user();
206 $this->setUser($user);
208 $generator->create_audience([
209 'reportid' => $report->get('id'),
210 'classname' => manual::class,
211 'configdata' => ['users' => [$user->id]],
214 // User has view capability and belongs to an audience.
215 permission::require_can_view_report($report);
217 $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
218 unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
220 // User does not have view capability and belongs to an audience.
221 $this->expectException(report_access_exception::class);
222 $this->expectExceptionMessage('You cannot view this report');
223 permission::require_can_view_report($report);
227 * Test whether user can view report when custom reports are disabled
229 public function test_require_can_view_report_disabled(): void {
230 $this->resetAfterTest();
231 $this->setAdminUser();
233 set_config('enablecustomreports', 0);
235 /** @var core_reportbuilder_generator $generator */
236 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
237 $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
239 $this->expectException(report_access_exception::class);
240 $this->expectExceptionMessage('You cannot view this report');
241 permission::require_can_view_report($report);
245 * Test that user cannot edit system reports
247 public function test_require_can_edit_report_system_report(): void {
248 global $CFG;
249 require_once("{$CFG->dirroot}/reportbuilder/tests/fixtures/system_report_available.php");
251 $this->resetAfterTest();
252 $this->setAdminUser();
254 $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
256 $this->expectException(report_access_exception::class);
257 $this->expectExceptionMessage('You cannot edit this report');
258 permission::require_can_edit_report($systemreport->get_report_persistent());
262 * Test that user cannot edit any reports without capabilities
264 public function test_require_can_edit_report_none(): void {
265 $this->resetAfterTest();
267 $user = $this->getDataGenerator()->create_user();
268 $this->setUser($user);
270 /** @var core_reportbuilder_generator $generator */
271 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
272 $report = $generator->create_report(['name' => 'User', 'source' => users::class]);
274 $this->expectException(report_access_exception::class);
275 $this->expectExceptionMessage('You cannot edit this report');
276 permission::require_can_edit_report($report);
280 * Test that user can edit their own reports
282 public function test_require_can_edit_report_own(): void {
283 global $DB;
285 $this->resetAfterTest();
287 $user = $this->getDataGenerator()->create_user();
288 $this->setUser($user);
290 $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
291 assign_capability('moodle/reportbuilder:edit', CAP_ALLOW, $userrole, context_system::instance());
293 /** @var core_reportbuilder_generator $generator */
294 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
296 // Confirm user can edit their own report.
297 $reportuser = $generator->create_report(['name' => 'User', 'source' => users::class]);
298 permission::require_can_edit_report($reportuser);
300 // Create a report by another user, confirm current user cannot edit it.
301 $reportadmin = $generator->create_report(['name' => 'Admin', 'source' => users::class, 'usercreated' => get_admin()->id]);
303 $this->expectException(report_access_exception::class);
304 $this->expectExceptionMessage('You cannot edit this report');
305 permission::require_can_edit_report($reportadmin);
309 * Test that user can edit any reports
311 public function test_require_can_edit_report_all(): void {
312 global $DB;
314 $this->resetAfterTest();
316 $user = $this->getDataGenerator()->create_user();
317 $this->setUser($user);
319 $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
320 assign_capability('moodle/reportbuilder:editall', CAP_ALLOW, $userrole, context_system::instance());
322 /** @var core_reportbuilder_generator $generator */
323 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
325 // Confirm user can edit their own report.
326 $reportuser = $generator->create_report(['name' => 'User', 'source' => users::class]);
327 permission::require_can_edit_report($reportuser);
329 // Create a report by another user, confirm current user can edit it.
330 $reportadmin = $generator->create_report(['name' => 'Admin', 'source' => users::class, 'usercreated' => get_admin()->id]);
331 permission::require_can_edit_report($reportadmin);
335 * Test whether user can edit report when custom reports are disabled
337 public function test_require_can_edit_report_disabled(): void {
338 $this->resetAfterTest();
339 $this->setAdminUser();
341 set_config('enablecustomreports', 0);
343 /** @var core_reportbuilder_generator $generator */
344 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
345 $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
347 $this->expectException(report_access_exception::class);
348 $this->expectExceptionMessage('You cannot edit this report');
349 permission::require_can_edit_report($report);
353 * Test that user can create a new report
355 public function test_require_can_create_report(): void {
356 $this->resetAfterTest();
358 // User has edit capability.
359 $user = $this->getDataGenerator()->create_user();
360 $this->setUser($user);
362 $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
363 assign_capability('moodle/reportbuilder:edit', CAP_ALLOW, $roleid, context_system::instance());
364 role_assign($roleid, $user->id, context_system::instance()->id);
366 try {
367 permission::require_can_create_report((int)$user->id);
368 } catch (Throwable $exception) {
369 $this->fail($exception->getMessage());
372 // User has editall capability.
373 $user2 = $this->getDataGenerator()->create_user();
374 $this->setUser($user2);
376 $roleid2 = create_role('Dummy role 2', 'dummyrole2', 'dummy role 2 description');
377 assign_capability('moodle/reportbuilder:editall', CAP_ALLOW, $roleid2, context_system::instance());
378 role_assign($roleid2, $user2->id, context_system::instance()->id);
380 try {
381 permission::require_can_create_report((int)$user2->id);
382 } catch (Throwable $exception) {
383 $this->fail($exception->getMessage());
386 // User has no capability.
387 $user3 = $this->getDataGenerator()->create_user();
388 $this->setUser($user3);
390 $this->expectException(report_access_exception::class);
391 $this->expectExceptionMessage('You cannot create a new report');
392 permission::require_can_create_report((int)$user3->id);
396 * Test whether user can create report when custom reports are disabled
398 public function test_require_can_create_report_disabled(): void {
399 $this->resetAfterTest();
400 $this->setAdminUser();
402 set_config('enablecustomreports', 0);
404 /** @var core_reportbuilder_generator $generator */
405 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
406 $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
408 $this->expectException(report_access_exception::class);
409 $this->expectExceptionMessage('You cannot create a new report');
410 permission::require_can_create_report();
414 * Data provider for {@see test_can_create_report_limit_reached}
416 * @return array
418 public function can_create_report_limit_reached_provider(): array {
419 return [
420 [0, 1, true],
421 [1, 1, false],
422 [2, 1, true],
423 [1, 2, false],
428 * Test whether user can create report when limit report are reache
429 * @param int $customreportslimit
430 * @param int $existingreports
431 * @param bool $expected
432 * @dataProvider can_create_report_limit_reached_provider
434 public function test_can_create_report_limit_reached(int $customreportslimit, int $existingreports, bool $expected): void {
435 global $CFG;
437 $this->resetAfterTest();
438 $this->setAdminUser();
440 /** @var core_reportbuilder_generator $generator */
441 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
442 for ($i = 1; $i <= $existingreports; $i++) {
443 $generator->create_report(['name' => 'Report limited '.$i, 'source' => users::class]);
446 // Set current custom report limit, and check whether user can create reports.
447 $CFG->customreportslimit = $customreportslimit;
448 $this->assertEquals($expected, permission::can_create_report());