Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
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
declare(strict_types=1);
18
 
19
namespace core_reportbuilder;
20
 
21
use advanced_testcase;
22
use context_system;
1441 ariadna 23
use core_reportbuilder\exception\report_access_exception;
1 efrain 24
use core_reportbuilder_generator;
25
use Throwable;
26
use core_user\reportbuilder\datasource\users;
27
use core_reportbuilder\reportbuilder\audience\manual;
28
 
29
/**
30
 * Unit tests for the report permission class
31
 *
32
 * @package     core_reportbuilder
33
 * @covers      \core_reportbuilder\permission
34
 * @copyright   2021 Paul Holden <paulh@moodle.com>
35
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 */
1441 ariadna 37
final class permission_test extends advanced_testcase {
1 efrain 38
 
39
    /**
40
     * Test whether user can view reports list
41
     */
42
    public function test_require_can_view_reports_list(): void {
43
        global $DB;
44
 
45
        $this->resetAfterTest();
46
 
47
        // User with default permission.
48
        $user = $this->getDataGenerator()->create_user();
49
        $this->setUser($user);
50
 
51
        try {
52
            permission::require_can_view_reports_list();
53
        } catch (Throwable $exception) {
54
            $this->fail($exception->getMessage());
55
        }
56
 
57
        // User without permission.
58
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
59
        unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
60
 
61
        $this->expectException(report_access_exception::class);
62
        $this->expectExceptionMessage('You cannot view this report');
63
        permission::require_can_view_reports_list();
64
    }
65
 
66
    /**
67
     * Data provider for {@see test_require_can_view_reports_list_with_capability}
68
     *
69
     * @return array[]
70
     */
71
    public static function require_can_view_reports_list_with_capability_provider(): array {
72
        return [
73
            ['moodle/reportbuilder:edit'],
74
            ['moodle/reportbuilder:editall'],
75
            ['moodle/reportbuilder:viewall'],
76
        ];
77
    }
78
 
79
    /**
80
     * Test that viewing reports list observes capability to do so
81
     *
82
     * @param string $capability
83
     *
84
     * @dataProvider require_can_view_reports_list_with_capability_provider
85
     */
86
    public function test_require_can_view_reports_list_with_capability(string $capability): void {
87
        global $DB;
88
 
89
        $this->resetAfterTest();
90
 
91
        $user = $this->getDataGenerator()->create_user();
92
        $this->setUser($user);
93
 
94
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
95
 
96
        // Remove default capability, allow additional.
97
        unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
98
        assign_capability($capability, CAP_ALLOW, $userrole, context_system::instance());
99
 
100
        try {
101
            permission::require_can_view_reports_list();
102
        } catch (Throwable $exception) {
103
            $this->fail($exception->getMessage());
104
        }
105
    }
106
 
107
    /**
108
     * Test whether user can view reports list when custom reports are disabled
109
     */
110
    public function test_require_can_view_reports_list_disabled(): void {
111
        $this->resetAfterTest();
112
        $this->setAdminUser();
113
 
114
        set_config('enablecustomreports', 0);
115
 
116
        $this->expectException(report_access_exception::class);
117
        $this->expectExceptionMessage('You cannot view this report');
118
        permission::require_can_view_reports_list();
119
    }
120
 
121
    /**
122
     * Test whether user can view specific report
123
     */
124
    public function test_require_can_view_report(): void {
125
        $this->resetAfterTest();
126
 
127
        /** @var core_reportbuilder_generator $generator */
128
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
129
        $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
130
 
131
        // User with permission.
132
        $this->setAdminUser();
133
        try {
134
            permission::require_can_view_report($report);
135
        } catch (Throwable $exception) {
136
            $this->fail($exception->getMessage());
137
        }
138
 
139
        // User without permission.
140
        $user = $this->getDataGenerator()->create_user();
141
        $this->setUser($user);
142
 
143
        $this->expectException(report_access_exception::class);
144
        $this->expectExceptionMessage('You cannot view this report');
145
        permission::require_can_view_report($report);
146
    }
147
 
148
    /**
149
     * Data provider for {@see test_require_can_view_report_with_capability}
150
     *
151
     * @return array[]
152
     */
153
    public static function require_can_view_report_with_capability_provider(): array {
154
        return [
155
            ['moodle/reportbuilder:editall'],
156
            ['moodle/reportbuilder:viewall'],
157
        ];
158
    }
159
 
160
    /**
161
     * Test whether user can view specific report when they have capability to view all reports
162
     *
163
     * @param string $capability
164
     *
165
     * @dataProvider require_can_view_report_with_capability_provider
166
     */
167
    public function test_require_can_view_report_with_capability(string $capability): void {
168
        global $DB;
169
 
170
        $this->resetAfterTest();
171
 
172
        // Admin creates a report, no audience.
173
        $this->setAdminUser();
174
 
175
        /** @var core_reportbuilder_generator $generator */
176
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
177
        $report = $generator->create_report(['name' => 'Admin report', 'source' => users::class]);
178
 
179
        // Switch to new user, assign capability.
180
        $user = $this->getDataGenerator()->create_user();
181
        $this->setUser($user);
182
 
183
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
184
        assign_capability($capability, CAP_ALLOW, $userrole, context_system::instance());
185
 
186
        try {
187
            permission::require_can_view_report($report);
188
        } catch (Throwable $exception) {
189
            $this->fail($exception->getMessage());
190
        }
191
    }
192
 
193
    /**
194
     * Test whether user can view specific report when it belongs to an audience
195
     */
196
    public function test_require_can_view_report_with_audience(): void {
197
        global $DB;
198
 
199
        $this->resetAfterTest();
200
 
201
        /** @var core_reportbuilder_generator $generator */
202
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
203
        $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
204
 
205
        // User without permission.
206
        $user = $this->getDataGenerator()->create_user();
207
        $this->setUser($user);
208
 
209
        $generator->create_audience([
210
            'reportid' => $report->get('id'),
211
            'classname' => manual::class,
212
            'configdata' => ['users' => [$user->id]],
213
        ]);
214
 
215
        // User has view capability and belongs to an audience.
216
        permission::require_can_view_report($report);
217
 
218
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
219
        unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
220
 
221
        // User does not have view capability and belongs to an audience.
222
        $this->expectException(report_access_exception::class);
223
        $this->expectExceptionMessage('You cannot view this report');
224
        permission::require_can_view_report($report);
225
    }
226
 
227
    /**
228
     * Test whether user can view report when custom reports are disabled
229
     */
230
    public function test_require_can_view_report_disabled(): void {
231
        $this->resetAfterTest();
232
        $this->setAdminUser();
233
 
234
        set_config('enablecustomreports', 0);
235
 
236
        /** @var core_reportbuilder_generator $generator */
237
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
238
        $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
239
 
240
        $this->expectException(report_access_exception::class);
241
        $this->expectExceptionMessage('You cannot view this report');
242
        permission::require_can_view_report($report);
243
    }
244
 
245
    /**
246
     * Test that user cannot edit system reports
247
     */
248
    public function test_require_can_edit_report_system_report(): void {
249
        global $CFG;
250
        require_once("{$CFG->dirroot}/reportbuilder/tests/fixtures/system_report_available.php");
251
 
252
        $this->resetAfterTest();
253
        $this->setAdminUser();
254
 
255
        $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
256
 
257
        $this->expectException(report_access_exception::class);
258
        $this->expectExceptionMessage('You cannot edit this report');
259
        permission::require_can_edit_report($systemreport->get_report_persistent());
260
    }
261
 
262
    /**
263
     * Test that user cannot edit any reports without capabilities
264
     */
265
    public function test_require_can_edit_report_none(): void {
266
        $this->resetAfterTest();
267
 
268
        $user = $this->getDataGenerator()->create_user();
269
        $this->setUser($user);
270
 
271
        /** @var core_reportbuilder_generator $generator */
272
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
273
        $report = $generator->create_report(['name' => 'User', 'source' => users::class]);
274
 
275
        $this->expectException(report_access_exception::class);
276
        $this->expectExceptionMessage('You cannot edit this report');
277
        permission::require_can_edit_report($report);
278
    }
279
 
280
    /**
281
     * Test that user can edit their own reports
282
     */
283
    public function test_require_can_edit_report_own(): void {
284
        global $DB;
285
 
286
        $this->resetAfterTest();
287
 
288
        $user = $this->getDataGenerator()->create_user();
289
        $this->setUser($user);
290
 
291
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
292
        assign_capability('moodle/reportbuilder:edit', CAP_ALLOW, $userrole, context_system::instance());
293
 
294
        /** @var core_reportbuilder_generator $generator */
295
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
296
 
297
        // Confirm user can edit their own report.
298
        $reportuser = $generator->create_report(['name' => 'User', 'source' => users::class]);
299
        permission::require_can_edit_report($reportuser);
300
 
301
        // Create a report by another user, confirm current user cannot edit it.
302
        $reportadmin = $generator->create_report(['name' => 'Admin', 'source' => users::class, 'usercreated' => get_admin()->id]);
303
 
304
        $this->expectException(report_access_exception::class);
305
        $this->expectExceptionMessage('You cannot edit this report');
306
        permission::require_can_edit_report($reportadmin);
307
    }
308
 
309
    /**
310
     * Test that user can edit any reports
311
     */
312
    public function test_require_can_edit_report_all(): void {
313
        global $DB;
314
 
315
        $this->resetAfterTest();
316
 
317
        $user = $this->getDataGenerator()->create_user();
318
        $this->setUser($user);
319
 
320
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
321
        assign_capability('moodle/reportbuilder:editall', CAP_ALLOW, $userrole, context_system::instance());
322
 
323
        /** @var core_reportbuilder_generator $generator */
324
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
325
 
326
        // Confirm user can edit their own report.
327
        $reportuser = $generator->create_report(['name' => 'User', 'source' => users::class]);
328
        permission::require_can_edit_report($reportuser);
329
 
330
        // Create a report by another user, confirm current user can edit it.
331
        $reportadmin = $generator->create_report(['name' => 'Admin', 'source' => users::class, 'usercreated' => get_admin()->id]);
332
        permission::require_can_edit_report($reportadmin);
333
    }
334
 
335
    /**
336
     * Test whether user can edit report when custom reports are disabled
337
     */
338
    public function test_require_can_edit_report_disabled(): void {
339
        $this->resetAfterTest();
340
        $this->setAdminUser();
341
 
342
        set_config('enablecustomreports', 0);
343
 
344
        /** @var core_reportbuilder_generator $generator */
345
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
346
        $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
347
 
348
        $this->expectException(report_access_exception::class);
349
        $this->expectExceptionMessage('You cannot edit this report');
350
        permission::require_can_edit_report($report);
351
    }
352
 
353
    /**
354
     * Test that user can create a new report
355
     */
356
    public function test_require_can_create_report(): void {
357
        $this->resetAfterTest();
358
 
359
        // User has edit capability.
360
        $user = $this->getDataGenerator()->create_user();
361
        $this->setUser($user);
362
 
363
        $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
364
        assign_capability('moodle/reportbuilder:edit', CAP_ALLOW, $roleid, context_system::instance());
365
        role_assign($roleid, $user->id, context_system::instance()->id);
366
 
367
        try {
368
            permission::require_can_create_report((int)$user->id);
369
        } catch (Throwable $exception) {
370
            $this->fail($exception->getMessage());
371
        }
372
 
373
        // User has editall capability.
374
        $user2 = $this->getDataGenerator()->create_user();
375
        $this->setUser($user2);
376
 
377
        $roleid2 = create_role('Dummy role 2', 'dummyrole2', 'dummy role 2 description');
378
        assign_capability('moodle/reportbuilder:editall', CAP_ALLOW, $roleid2, context_system::instance());
379
        role_assign($roleid2, $user2->id, context_system::instance()->id);
380
 
381
        try {
382
            permission::require_can_create_report((int)$user2->id);
383
        } catch (Throwable $exception) {
384
            $this->fail($exception->getMessage());
385
        }
386
 
387
        // User has no capability.
388
        $user3 = $this->getDataGenerator()->create_user();
389
        $this->setUser($user3);
390
 
391
        $this->expectException(report_access_exception::class);
392
        $this->expectExceptionMessage('You cannot create a new report');
393
        permission::require_can_create_report((int)$user3->id);
394
    }
395
 
396
    /**
397
     * Test whether user can create report when custom reports are disabled
398
     */
399
    public function test_require_can_create_report_disabled(): void {
400
        $this->resetAfterTest();
401
        $this->setAdminUser();
402
 
403
        set_config('enablecustomreports', 0);
404
 
405
        /** @var core_reportbuilder_generator $generator */
406
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
407
        $report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
408
 
409
        $this->expectException(report_access_exception::class);
410
        $this->expectExceptionMessage('You cannot create a new report');
411
        permission::require_can_create_report();
412
    }
413
 
414
    /**
415
     * Data provider for {@see test_can_create_report_limit_reached}
416
     *
417
     * @return array
418
     */
1441 ariadna 419
    public static function can_create_report_limit_reached_provider(): array {
1 efrain 420
        return [
421
            [0, 1, true],
422
            [1, 1, false],
423
            [2, 1, true],
424
            [1, 2, false],
425
        ];
426
    }
427
 
428
    /**
429
     * Test whether user can create report when limit report are reache
430
     * @param int $customreportslimit
431
     * @param int $existingreports
432
     * @param bool $expected
433
     * @dataProvider can_create_report_limit_reached_provider
434
     */
435
    public function test_can_create_report_limit_reached(int $customreportslimit, int $existingreports, bool $expected): void {
436
        global $CFG;
437
 
438
        $this->resetAfterTest();
439
        $this->setAdminUser();
440
 
441
        /** @var core_reportbuilder_generator $generator */
442
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
443
        for ($i = 1; $i <= $existingreports; $i++) {
444
            $generator->create_report(['name' => 'Report limited '.$i, 'source' => users::class]);
445
        }
446
 
447
        // Set current custom report limit, and check whether user can create reports.
448
        $CFG->customreportslimit = $customreportslimit;
449
        $this->assertEquals($expected, permission::can_create_report());
450
    }
1441 ariadna 451
 
452
    /**
453
     * Test that user can duplicate a report
454
     */
455
    public function test_require_can_duplicate_report(): void {
456
        global $DB, $CFG;
457
 
458
        $this->resetAfterTest();
459
 
460
        $user = $this->getDataGenerator()->create_user();
461
        $this->setUser($user);
462
 
463
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
464
        assign_capability('moodle/reportbuilder:edit', CAP_ALLOW, $userrole, context_system::instance());
465
 
466
        /** @var core_reportbuilder_generator $generator */
467
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
468
 
469
        // Confirm user can duplicate their own report.
470
        $reportuser = $generator->create_report(['name' => 'User', 'source' => users::class]);
471
        permission::require_can_duplicate_report($reportuser);
472
 
473
        // Create a report by another user, confirm current user cannot duplicate it without proper permission.
474
        $reportadmin = $generator->create_report(['name' => 'Admin', 'source' => users::class, 'usercreated' => get_admin()->id]);
475
        try {
476
            permission::require_can_duplicate_report($reportadmin);
477
            $this->fail('Exception expected');
478
        } catch (report_access_exception $e) {
479
            $this->assertStringContainsString('You cannot duplicate this report', $e->getMessage());
480
        }
481
 
482
        assign_capability('moodle/reportbuilder:editall', CAP_ALLOW, $userrole, context_system::instance());
483
        permission::require_can_duplicate_report($reportadmin);
484
 
485
        // Set current custom report limit, and check whether user can duplicate the report.
486
        $CFG->customreportslimit = 1;
487
        $this->expectException(report_access_exception::class);
488
        $this->expectExceptionMessage('You cannot duplicate this report');
489
        permission::require_can_duplicate_report($reportuser);
490
    }
1 efrain 491
}