Proyectos de Subversion Moodle

Rev

| 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;
23
use core_reportbuilder_generator;
24
use Throwable;
25
use core_user\reportbuilder\datasource\users;
26
use core_reportbuilder\reportbuilder\audience\manual;
27
 
28
/**
29
 * Unit tests for the report permission class
30
 *
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
35
 */
36
class permission_test extends advanced_testcase {
37
 
38
    /**
39
     * Test whether user can view reports list
40
     */
41
    public function test_require_can_view_reports_list(): void {
42
        global $DB;
43
 
44
        $this->resetAfterTest();
45
 
46
        // User with default permission.
47
        $user = $this->getDataGenerator()->create_user();
48
        $this->setUser($user);
49
 
50
        try {
51
            permission::require_can_view_reports_list();
52
        } catch (Throwable $exception) {
53
            $this->fail($exception->getMessage());
54
        }
55
 
56
        // User without permission.
57
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
58
        unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
59
 
60
        $this->expectException(report_access_exception::class);
61
        $this->expectExceptionMessage('You cannot view this report');
62
        permission::require_can_view_reports_list();
63
    }
64
 
65
    /**
66
     * Data provider for {@see test_require_can_view_reports_list_with_capability}
67
     *
68
     * @return array[]
69
     */
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'],
75
        ];
76
    }
77
 
78
    /**
79
     * Test that viewing reports list observes capability to do so
80
     *
81
     * @param string $capability
82
     *
83
     * @dataProvider require_can_view_reports_list_with_capability_provider
84
     */
85
    public function test_require_can_view_reports_list_with_capability(string $capability): void {
86
        global $DB;
87
 
88
        $this->resetAfterTest();
89
 
90
        $user = $this->getDataGenerator()->create_user();
91
        $this->setUser($user);
92
 
93
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
94
 
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());
98
 
99
        try {
100
            permission::require_can_view_reports_list();
101
        } catch (Throwable $exception) {
102
            $this->fail($exception->getMessage());
103
        }
104
    }
105
 
106
    /**
107
     * Test whether user can view reports list when custom reports are disabled
108
     */
109
    public function test_require_can_view_reports_list_disabled(): void {
110
        $this->resetAfterTest();
111
        $this->setAdminUser();
112
 
113
        set_config('enablecustomreports', 0);
114
 
115
        $this->expectException(report_access_exception::class);
116
        $this->expectExceptionMessage('You cannot view this report');
117
        permission::require_can_view_reports_list();
118
    }
119
 
120
    /**
121
     * Test whether user can view specific report
122
     */
123
    public function test_require_can_view_report(): void {
124
        $this->resetAfterTest();
125
 
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]);
129
 
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());
136
        }
137
 
138
        // User without permission.
139
        $user = $this->getDataGenerator()->create_user();
140
        $this->setUser($user);
141
 
142
        $this->expectException(report_access_exception::class);
143
        $this->expectExceptionMessage('You cannot view this report');
144
        permission::require_can_view_report($report);
145
    }
146
 
147
    /**
148
     * Data provider for {@see test_require_can_view_report_with_capability}
149
     *
150
     * @return array[]
151
     */
152
    public static function require_can_view_report_with_capability_provider(): array {
153
        return [
154
            ['moodle/reportbuilder:editall'],
155
            ['moodle/reportbuilder:viewall'],
156
        ];
157
    }
158
 
159
    /**
160
     * Test whether user can view specific report when they have capability to view all reports
161
     *
162
     * @param string $capability
163
     *
164
     * @dataProvider require_can_view_report_with_capability_provider
165
     */
166
    public function test_require_can_view_report_with_capability(string $capability): void {
167
        global $DB;
168
 
169
        $this->resetAfterTest();
170
 
171
        // Admin creates a report, no audience.
172
        $this->setAdminUser();
173
 
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]);
177
 
178
        // Switch to new user, assign capability.
179
        $user = $this->getDataGenerator()->create_user();
180
        $this->setUser($user);
181
 
182
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
183
        assign_capability($capability, CAP_ALLOW, $userrole, context_system::instance());
184
 
185
        try {
186
            permission::require_can_view_report($report);
187
        } catch (Throwable $exception) {
188
            $this->fail($exception->getMessage());
189
        }
190
    }
191
 
192
    /**
193
     * Test whether user can view specific report when it belongs to an audience
194
     */
195
    public function test_require_can_view_report_with_audience(): void {
196
        global $DB;
197
 
198
        $this->resetAfterTest();
199
 
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]);
203
 
204
        // User without permission.
205
        $user = $this->getDataGenerator()->create_user();
206
        $this->setUser($user);
207
 
208
        $generator->create_audience([
209
            'reportid' => $report->get('id'),
210
            'classname' => manual::class,
211
            'configdata' => ['users' => [$user->id]],
212
        ]);
213
 
214
        // User has view capability and belongs to an audience.
215
        permission::require_can_view_report($report);
216
 
217
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
218
        unassign_capability('moodle/reportbuilder:view', $userrole, context_system::instance());
219
 
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);
224
    }
225
 
226
    /**
227
     * Test whether user can view report when custom reports are disabled
228
     */
229
    public function test_require_can_view_report_disabled(): void {
230
        $this->resetAfterTest();
231
        $this->setAdminUser();
232
 
233
        set_config('enablecustomreports', 0);
234
 
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]);
238
 
239
        $this->expectException(report_access_exception::class);
240
        $this->expectExceptionMessage('You cannot view this report');
241
        permission::require_can_view_report($report);
242
    }
243
 
244
    /**
245
     * Test that user cannot edit system reports
246
     */
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");
250
 
251
        $this->resetAfterTest();
252
        $this->setAdminUser();
253
 
254
        $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
255
 
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());
259
    }
260
 
261
    /**
262
     * Test that user cannot edit any reports without capabilities
263
     */
264
    public function test_require_can_edit_report_none(): void {
265
        $this->resetAfterTest();
266
 
267
        $user = $this->getDataGenerator()->create_user();
268
        $this->setUser($user);
269
 
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]);
273
 
274
        $this->expectException(report_access_exception::class);
275
        $this->expectExceptionMessage('You cannot edit this report');
276
        permission::require_can_edit_report($report);
277
    }
278
 
279
    /**
280
     * Test that user can edit their own reports
281
     */
282
    public function test_require_can_edit_report_own(): void {
283
        global $DB;
284
 
285
        $this->resetAfterTest();
286
 
287
        $user = $this->getDataGenerator()->create_user();
288
        $this->setUser($user);
289
 
290
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
291
        assign_capability('moodle/reportbuilder:edit', CAP_ALLOW, $userrole, context_system::instance());
292
 
293
        /** @var core_reportbuilder_generator $generator */
294
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
295
 
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);
299
 
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]);
302
 
303
        $this->expectException(report_access_exception::class);
304
        $this->expectExceptionMessage('You cannot edit this report');
305
        permission::require_can_edit_report($reportadmin);
306
    }
307
 
308
    /**
309
     * Test that user can edit any reports
310
     */
311
    public function test_require_can_edit_report_all(): void {
312
        global $DB;
313
 
314
        $this->resetAfterTest();
315
 
316
        $user = $this->getDataGenerator()->create_user();
317
        $this->setUser($user);
318
 
319
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user']);
320
        assign_capability('moodle/reportbuilder:editall', CAP_ALLOW, $userrole, context_system::instance());
321
 
322
        /** @var core_reportbuilder_generator $generator */
323
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
324
 
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);
328
 
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);
332
    }
333
 
334
    /**
335
     * Test whether user can edit report when custom reports are disabled
336
     */
337
    public function test_require_can_edit_report_disabled(): void {
338
        $this->resetAfterTest();
339
        $this->setAdminUser();
340
 
341
        set_config('enablecustomreports', 0);
342
 
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]);
346
 
347
        $this->expectException(report_access_exception::class);
348
        $this->expectExceptionMessage('You cannot edit this report');
349
        permission::require_can_edit_report($report);
350
    }
351
 
352
    /**
353
     * Test that user can create a new report
354
     */
355
    public function test_require_can_create_report(): void {
356
        $this->resetAfterTest();
357
 
358
        // User has edit capability.
359
        $user = $this->getDataGenerator()->create_user();
360
        $this->setUser($user);
361
 
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);
365
 
366
        try {
367
            permission::require_can_create_report((int)$user->id);
368
        } catch (Throwable $exception) {
369
            $this->fail($exception->getMessage());
370
        }
371
 
372
        // User has editall capability.
373
        $user2 = $this->getDataGenerator()->create_user();
374
        $this->setUser($user2);
375
 
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);
379
 
380
        try {
381
            permission::require_can_create_report((int)$user2->id);
382
        } catch (Throwable $exception) {
383
            $this->fail($exception->getMessage());
384
        }
385
 
386
        // User has no capability.
387
        $user3 = $this->getDataGenerator()->create_user();
388
        $this->setUser($user3);
389
 
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);
393
    }
394
 
395
    /**
396
     * Test whether user can create report when custom reports are disabled
397
     */
398
    public function test_require_can_create_report_disabled(): void {
399
        $this->resetAfterTest();
400
        $this->setAdminUser();
401
 
402
        set_config('enablecustomreports', 0);
403
 
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]);
407
 
408
        $this->expectException(report_access_exception::class);
409
        $this->expectExceptionMessage('You cannot create a new report');
410
        permission::require_can_create_report();
411
    }
412
 
413
    /**
414
     * Data provider for {@see test_can_create_report_limit_reached}
415
     *
416
     * @return array
417
     */
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],
424
        ];
425
    }
426
 
427
    /**
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
433
     */
434
    public function test_can_create_report_limit_reached(int $customreportslimit, int $existingreports, bool $expected): void {
435
        global $CFG;
436
 
437
        $this->resetAfterTest();
438
        $this->setAdminUser();
439
 
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]);
444
        }
445
 
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());
449
    }
450
}