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
/**
18
 * External tests.
19
 *
20
 * @package    tool_dataprivacy
21
 * @copyright  2018 Jun Pataleta
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace tool_dataprivacy\external;
26
 
27
use core_external\external_api;
28
use externallib_advanced_testcase;
29
use tool_dataprivacy\api;
30
use tool_dataprivacy\data_request;
31
use tool_dataprivacy\context_instance;
32
use tool_dataprivacy\external;
33
 
34
defined('MOODLE_INTERNAL') || die();
35
global $CFG;
36
 
37
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
38
 
39
/**
40
 * External testcase.
41
 *
42
 * @package    tool_dataprivacy
43
 * @copyright  2018 Jun Pataleta
44
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45
 */
46
class external_test extends externallib_advanced_testcase {
47
 
48
    /**
49
     * Test for external::approve_data_request() with the user not logged in.
50
     */
11 efrain 51
    public function test_approve_data_request_not_logged_in(): void {
1 efrain 52
        $this->resetAfterTest();
53
 
54
        $generator = new \testing_data_generator();
55
        $requester = $generator->create_user();
56
        $comment = 'sample comment';
57
 
58
        // Test data request creation.
59
        $this->setUser($requester);
60
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
61
 
62
        // Log out the user and set force login to true.
63
        $this->setUser();
64
 
65
        $this->expectException(\require_login_exception::class);
66
        external::approve_data_request($datarequest->get('id'));
67
    }
68
 
69
    /**
70
     * Test for external::approve_data_request() with the user not having a DPO role.
71
     */
11 efrain 72
    public function test_approve_data_request_not_dpo(): void {
1 efrain 73
        $this->resetAfterTest();
74
 
75
        $generator = new \testing_data_generator();
76
        $requester = $generator->create_user();
77
        $comment = 'sample comment';
78
 
79
        // Test data request creation.
80
        $this->setUser($requester);
81
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
82
 
83
        // Login as the requester.
84
        $this->setUser($requester);
85
        $this->expectException(\required_capability_exception::class);
86
        external::approve_data_request($datarequest->get('id'));
87
    }
88
 
89
    /**
90
     * Test for external::approve_data_request() for request that's not ready for approval
91
     */
11 efrain 92
    public function test_approve_data_request_not_waiting_for_approval(): void {
1 efrain 93
        $this->resetAfterTest();
94
 
95
        $generator = new \testing_data_generator();
96
        $requester = $generator->create_user();
97
        $comment = 'sample comment';
98
 
99
        // Test data request creation.
100
        $this->setUser($requester);
101
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
102
        $datarequest->set('status', api::DATAREQUEST_STATUS_CANCELLED)->save();
103
 
104
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
105
        $this->setAdminUser();
106
        $this->expectException(\moodle_exception::class);
107
        external::approve_data_request($datarequest->get('id'));
108
    }
109
 
110
    /**
111
     * Test for external::approve_data_request()
112
     */
11 efrain 113
    public function test_approve_data_request(): void {
1 efrain 114
        $this->resetAfterTest();
115
 
116
        $generator = new \testing_data_generator();
117
        $requester = $generator->create_user();
118
        $comment = 'sample comment';
119
 
120
        // Test data request creation.
121
        $this->setUser($requester);
122
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
123
 
124
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
125
        $this->setAdminUser();
126
        api::update_request_status($datarequest->get('id'), api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
127
        $result = external::approve_data_request($datarequest->get('id'));
128
        $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
129
        $this->assertTrue($return->result);
130
        $this->assertEmpty($return->warnings);
131
    }
132
 
133
    /**
134
     * Test for external::approve_data_request() for a non-existent request ID.
135
     */
11 efrain 136
    public function test_approve_data_request_non_existent(): void {
1 efrain 137
        $this->resetAfterTest();
138
 
139
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
140
        $this->setAdminUser();
141
 
142
        $result = external::approve_data_request(1);
143
 
144
        $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
145
        $this->assertFalse($return->result);
146
        $this->assertCount(1, $return->warnings);
147
        $warning = reset($return->warnings);
148
        $this->assertEquals('errorrequestnotfound', $warning['warningcode']);
149
    }
150
 
151
    /**
152
     * Test for external::cancel_data_request() of another user.
153
     */
11 efrain 154
    public function test_cancel_data_request_other_user(): void {
1 efrain 155
        $this->resetAfterTest();
156
 
157
        $generator = new \testing_data_generator();
158
        $requester = $generator->create_user();
159
        $otheruser = $generator->create_user();
160
        $comment = 'sample comment';
161
 
162
        // Test data request creation.
163
        $this->setUser($requester);
164
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
165
 
166
        // Login as other user.
167
        $this->setUser($otheruser);
168
 
169
        $result = external::cancel_data_request($datarequest->get('id'));
170
        $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
171
        $this->assertFalse($return->result);
172
        $this->assertCount(1, $return->warnings);
173
        $warning = reset($return->warnings);
174
        $this->assertEquals('errorrequestnotfound', $warning['warningcode']);
175
    }
176
 
177
    /**
178
     * Test cancellation of a request where you are the requester of another user's data.
179
     */
11 efrain 180
    public function test_cancel_data_request_other_user_as_requester(): void {
1 efrain 181
        $this->resetAfterTest();
182
 
183
        $generator = new \testing_data_generator();
184
        $requester = $generator->create_user();
185
        $otheruser = $generator->create_user();
186
        $comment = 'sample comment';
187
 
188
        // Assign requester as otheruser'sparent.
189
        $systemcontext = \context_system::instance();
190
        $parentrole = $generator->create_role();
191
        assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
192
        role_assign($parentrole, $requester->id, \context_user::instance($otheruser->id));
193
 
194
        // Test data request creation.
195
        $this->setUser($requester);
196
        $datarequest = api::create_data_request($otheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
197
 
198
        $result = external::cancel_data_request($datarequest->get('id'));
199
        $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
200
        $this->assertTrue($return->result);
201
        $this->assertEmpty($return->warnings);
202
    }
203
 
204
    /**
205
     * Test cancellation of a request where you are the requester of another user's data.
206
     */
11 efrain 207
    public function test_cancel_data_request_requester_lost_permissions(): void {
1 efrain 208
        $this->resetAfterTest();
209
 
210
        $generator = new \testing_data_generator();
211
        $requester = $generator->create_user();
212
        $otheruser = $generator->create_user();
213
        $comment = 'sample comment';
214
 
215
        // Assign requester as otheruser'sparent.
216
        $systemcontext = \context_system::instance();
217
        $parentrole = $generator->create_role();
218
        assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
219
        role_assign($parentrole, $requester->id, \context_user::instance($otheruser->id));
220
 
221
        $this->setUser($requester);
222
        $datarequest = api::create_data_request($otheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
223
 
224
        // Unassign the role.
225
        role_unassign($parentrole, $requester->id, \context_user::instance($otheruser->id)->id);
226
 
227
        // This user can no longer make the request.
228
        $this->expectException(\required_capability_exception::class);
229
 
230
        $result = external::cancel_data_request($datarequest->get('id'));
231
    }
232
 
233
    /**
234
     * Test cancellation of a request where you are the requester of another user's data.
235
     */
11 efrain 236
    public function test_cancel_data_request_other_user_as_child(): void {
1 efrain 237
        $this->resetAfterTest();
238
 
239
        $generator = new \testing_data_generator();
240
        $requester = $generator->create_user();
241
        $otheruser = $generator->create_user();
242
        $comment = 'sample comment';
243
 
244
        // Assign requester as otheruser'sparent.
245
        $systemcontext = \context_system::instance();
246
        $parentrole = $generator->create_role();
247
        assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
248
        role_assign($parentrole, $requester->id, \context_user::instance($otheruser->id));
249
 
250
        // Test data request creation.
251
        $this->setUser($otheruser);
252
        $datarequest = api::create_data_request($otheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
253
 
254
        $result = external::cancel_data_request($datarequest->get('id'));
255
        $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
256
        $this->assertTrue($return->result);
257
        $this->assertEmpty($return->warnings);
258
    }
259
 
260
    /**
261
     * Test for external::cancel_data_request()
262
     */
11 efrain 263
    public function test_cancel_data_request(): void {
1 efrain 264
        $this->resetAfterTest();
265
 
266
        $generator = new \testing_data_generator();
267
        $requester = $generator->create_user();
268
        $comment = 'sample comment';
269
 
270
        // Test data request creation.
271
        $this->setUser($requester);
272
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
273
 
274
        // Test cancellation.
275
        $this->setUser($requester);
276
        $result = external::cancel_data_request($datarequest->get('id'));
277
 
278
        $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
279
        $this->assertTrue($return->result);
280
        $this->assertEmpty($return->warnings);
281
    }
282
 
283
    /**
284
     * Test contact DPO.
285
     */
11 efrain 286
    public function test_contact_dpo(): void {
1 efrain 287
        $this->resetAfterTest();
288
 
289
        $generator = new \testing_data_generator();
290
        $user = $generator->create_user();
291
 
292
        $this->setUser($user);
293
        $message = 'Hello world!';
294
        $result = external::contact_dpo($message);
295
        $return = (object) external_api::clean_returnvalue(external::contact_dpo_returns(), $result);
296
        $this->assertTrue($return->result);
297
        $this->assertEmpty($return->warnings);
298
    }
299
 
300
    /**
301
     * Test contact DPO with message containing invalid input.
302
     */
11 efrain 303
    public function test_contact_dpo_with_nasty_input(): void {
1 efrain 304
        $this->resetAfterTest();
305
 
306
        $generator = new \testing_data_generator();
307
        $user = $generator->create_user();
308
 
309
        $this->setUser($user);
310
        $this->expectException('invalid_parameter_exception');
311
        external::contact_dpo('de<>\\..scription');
312
    }
313
 
314
    /**
315
     * Test for external::deny_data_request() with the user not logged in.
316
     */
11 efrain 317
    public function test_deny_data_request_not_logged_in(): void {
1 efrain 318
        $this->resetAfterTest();
319
 
320
        $generator = new \testing_data_generator();
321
        $requester = $generator->create_user();
322
        $comment = 'sample comment';
323
 
324
        // Test data request creation.
325
        $this->setUser($requester);
326
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
327
 
328
        // Log out.
329
        $this->setUser();
330
        $this->expectException(\require_login_exception::class);
331
        external::deny_data_request($datarequest->get('id'));
332
    }
333
 
334
    /**
335
     * Test for external::deny_data_request() with the user not having a DPO role.
336
     */
11 efrain 337
    public function test_deny_data_request_not_dpo(): void {
1 efrain 338
        $this->resetAfterTest();
339
 
340
        $generator = new \testing_data_generator();
341
        $requester = $generator->create_user();
342
        $comment = 'sample comment';
343
 
344
        $this->setUser($requester);
345
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
346
 
347
        // Login as the requester.
348
        $this->setUser($requester);
349
        $this->expectException(\required_capability_exception::class);
350
        external::deny_data_request($datarequest->get('id'));
351
    }
352
 
353
    /**
354
     * Test for external::deny_data_request() for request that's not ready for approval
355
     */
11 efrain 356
    public function test_deny_data_request_not_waiting_for_approval(): void {
1 efrain 357
        $this->resetAfterTest();
358
 
359
        $generator = new \testing_data_generator();
360
        $requester = $generator->create_user();
361
        $comment = 'sample comment';
362
 
363
        $this->setUser($requester);
364
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
365
        $datarequest->set('status', api::DATAREQUEST_STATUS_CANCELLED)->save();
366
 
367
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
368
        $this->setAdminUser();
369
        $this->expectException(\moodle_exception::class);
370
        external::deny_data_request($datarequest->get('id'));
371
    }
372
 
373
    /**
374
     * Test for external::deny_data_request()
375
     */
11 efrain 376
    public function test_deny_data_request(): void {
1 efrain 377
        $this->resetAfterTest();
378
 
379
        $generator = new \testing_data_generator();
380
        $requester = $generator->create_user();
381
        $comment = 'sample comment';
382
 
383
        $this->setUser($requester);
384
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
385
 
386
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
387
        $this->setAdminUser();
388
        api::update_request_status($datarequest->get('id'), api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
389
        $result = external::approve_data_request($datarequest->get('id'));
390
        $return = (object) external_api::clean_returnvalue(external::deny_data_request_returns(), $result);
391
        $this->assertTrue($return->result);
392
        $this->assertEmpty($return->warnings);
393
    }
394
 
395
    /**
396
     * Test for external::deny_data_request() for a non-existent request ID.
397
     */
11 efrain 398
    public function test_deny_data_request_non_existent(): void {
1 efrain 399
        $this->resetAfterTest();
400
 
401
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
402
        $this->setAdminUser();
403
        $result = external::deny_data_request(1);
404
 
405
        $return = (object) external_api::clean_returnvalue(external::deny_data_request_returns(), $result);
406
        $this->assertFalse($return->result);
407
        $this->assertCount(1, $return->warnings);
408
        $warning = reset($return->warnings);
409
        $this->assertEquals('errorrequestnotfound', $warning['warningcode']);
410
    }
411
 
412
    /**
413
     * Test for external::get_data_request() with the user not logged in.
414
     */
11 efrain 415
    public function test_get_data_request_not_logged_in(): void {
1 efrain 416
        $this->resetAfterTest();
417
 
418
        $generator = new \testing_data_generator();
419
        $requester = $generator->create_user();
420
        $comment = 'sample comment';
421
 
422
        $this->setUser($requester);
423
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
424
 
425
        $this->setUser();
426
        $this->expectException(\require_login_exception::class);
427
        external::get_data_request($datarequest->get('id'));
428
    }
429
 
430
    /**
431
     * Test for external::get_data_request() with the user not having a DPO role.
432
     */
11 efrain 433
    public function test_get_data_request_not_dpo(): void {
1 efrain 434
        $this->resetAfterTest();
435
 
436
        $generator = new \testing_data_generator();
437
        $requester = $generator->create_user();
438
        $otheruser = $generator->create_user();
439
        $comment = 'sample comment';
440
 
441
        $this->setUser($requester);
442
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
443
 
444
        // Login as the otheruser.
445
        $this->setUser($otheruser);
446
        $this->expectException(\required_capability_exception::class);
447
        external::get_data_request($datarequest->get('id'));
448
    }
449
 
450
    /**
451
     * Test for external::get_data_request()
452
     */
11 efrain 453
    public function test_get_data_request(): void {
1 efrain 454
        $this->resetAfterTest();
455
 
456
        $generator = new \testing_data_generator();
457
        $requester = $generator->create_user();
458
        $comment = 'sample comment';
459
 
460
        $this->setUser($requester);
461
        $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
462
 
463
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
464
        $this->setAdminUser();
465
        $result = external::get_data_request($datarequest->get('id'));
466
 
467
        $return = (object) external_api::clean_returnvalue(external::get_data_request_returns(), $result);
468
        $this->assertEquals(api::DATAREQUEST_TYPE_EXPORT, $return->result['type']);
469
        $this->assertEquals('sample comment', $return->result['comments']);
470
        $this->assertEquals($requester->id, $return->result['userid']);
471
        $this->assertEquals($requester->id, $return->result['requestedby']);
472
        $this->assertEmpty($return->warnings);
473
    }
474
 
475
    /**
476
     * Test for external::get_data_request() for a non-existent request ID.
477
     */
11 efrain 478
    public function test_get_data_request_non_existent(): void {
1 efrain 479
        $this->resetAfterTest();
480
 
481
        // Admin as DPO. (The default when no one's assigned as a DPO in the site).
482
        $this->setAdminUser();
483
        $this->expectException(\dml_missing_record_exception::class);
484
        external::get_data_request(1);
485
    }
486
 
487
    /**
488
     * Test for \tool_dataprivacy\external::set_context_defaults()
489
     * when called by a user that doesn't have the manage registry capability.
490
     */
11 efrain 491
    public function test_set_context_defaults_no_capability(): void {
1 efrain 492
        $this->resetAfterTest();
493
 
494
        $generator = $this->getDataGenerator();
495
        $user = $generator->create_user();
496
        $this->setUser($user);
497
        $this->expectException(\required_capability_exception::class);
498
        external::set_context_defaults(CONTEXT_COURSECAT, context_instance::INHERIT, context_instance::INHERIT, '', false);
499
    }
500
 
501
    /**
502
     * Test for \tool_dataprivacy\external::set_context_defaults().
503
     *
504
     * We're just checking the module context level here to test the WS function.
505
     * More testing is done in \tool_dataprivacy_api_testcase::test_set_context_defaults().
506
     *
507
     * @dataProvider get_options_provider
508
     * @param bool $modulelevel Whether defaults are to be applied on the module context level or for an activity only.
509
     * @param bool $override Whether to override instances.
510
     */
11 efrain 511
    public function test_set_context_defaults($modulelevel, $override): void {
1 efrain 512
        $this->resetAfterTest();
513
 
514
        $this->setAdminUser();
515
        $generator = $this->getDataGenerator();
516
 
517
        // Generate course cat, course, block, assignment, forum instances.
518
        $coursecat = $generator->create_category();
519
        $course = $generator->create_course(['category' => $coursecat->id]);
520
        $assign = $generator->create_module('assign', ['course' => $course->id]);
521
        list($course, $assigncm) = get_course_and_cm_from_instance($assign->id, 'assign');
522
        $assigncontext = \context_module::instance($assigncm->id);
523
 
524
        // Generate purpose and category.
525
        $category1 = api::create_category((object)['name' => 'Test category 1']);
526
        $category2 = api::create_category((object)['name' => 'Test category 2']);
527
        $purpose1 = api::create_purpose((object)[
528
            'name' => 'Test purpose 1', 'retentionperiod' => 'PT1M', 'lawfulbases' => 'gdpr_art_6_1_a'
529
        ]);
530
        $purpose2 = api::create_purpose((object)[
531
            'name' => 'Test purpose 2', 'retentionperiod' => 'PT1M', 'lawfulbases' => 'gdpr_art_6_1_a'
532
        ]);
533
 
534
        // Set a custom purpose and ID for this assignment instance.
535
        $assignctxinstance = api::set_context_instance((object) [
536
            'contextid' => $assigncontext->id,
537
            'purposeid' => $purpose1->get('id'),
538
            'categoryid' => $category1->get('id'),
539
        ]);
540
 
541
        $modulename = $modulelevel ? 'assign' : '';
542
        $categoryid = $category2->get('id');
543
        $purposeid = $purpose2->get('id');
544
        $result = external::set_context_defaults(CONTEXT_MODULE, $categoryid, $purposeid, $modulename, $override);
545
 
546
        // Extract the result.
547
        $return = external_api::clean_returnvalue(external::set_context_defaults_returns(), $result);
548
        $this->assertTrue($return['result']);
549
 
550
        // Check the assignment context instance.
551
        $instanceexists = context_instance::record_exists($assignctxinstance->get('id'));
552
        if ($override) {
553
            // The custom assign instance should have been deleted.
554
            $this->assertFalse($instanceexists);
555
        } else {
556
            // The custom assign instance should still exist.
557
            $this->assertTrue($instanceexists);
558
        }
559
 
560
        // Check the saved defaults.
561
        list($savedpurpose, $savedcategory) = \tool_dataprivacy\data_registry::get_defaults(CONTEXT_MODULE, $modulename);
562
        $this->assertEquals($categoryid, $savedcategory);
563
        $this->assertEquals($purposeid, $savedpurpose);
564
    }
565
 
566
    /**
567
     * Test for \tool_dataprivacy\external::get_category_options()
568
     * when called by a user that doesn't have the manage registry capability.
569
     */
11 efrain 570
    public function test_get_category_options_no_capability(): void {
1 efrain 571
        $this->resetAfterTest();
572
 
573
        $user = $this->getDataGenerator()->create_user();
574
        $this->setUser($user);
575
 
576
        $this->expectException(\required_capability_exception::class);
577
        external::get_category_options(true, true);
578
    }
579
 
580
    /**
581
     * Data provider for \tool_dataprivacy_external_testcase::test_XX_options().
582
     */
583
    public function get_options_provider() {
584
        return [
585
            [false, false],
586
            [false, true],
587
            [true, false],
588
            [true, true],
589
        ];
590
    }
591
 
592
    /**
593
     * Test for \tool_dataprivacy\external::get_category_options().
594
     *
595
     * @dataProvider get_options_provider
596
     * @param bool $includeinherit Whether "Inherit" would be included to the options.
597
     * @param bool $includenotset Whether "Not set" would be included to the options.
598
     */
11 efrain 599
    public function test_get_category_options($includeinherit, $includenotset): void {
1 efrain 600
        $this->resetAfterTest();
601
        $this->setAdminUser();
602
 
603
        // Prepare our expected options.
604
        $expectedoptions = [];
605
        if ($includeinherit) {
606
            $expectedoptions[] = [
607
                'id' => context_instance::INHERIT,
608
                'name' => get_string('inherit', 'tool_dataprivacy'),
609
            ];
610
        }
611
 
612
        if ($includenotset) {
613
            $expectedoptions[] = [
614
                'id' => context_instance::NOTSET,
615
                'name' => get_string('notset', 'tool_dataprivacy'),
616
            ];
617
        }
618
 
619
        for ($i = 1; $i <= 3; $i++) {
620
            $category = api::create_category((object)['name' => 'Category ' . $i]);
621
            $expectedoptions[] = [
622
                'id' => $category->get('id'),
623
                'name' => $category->get('name'),
624
            ];
625
        }
626
 
627
        // Call the WS function.
628
        $result = external::get_category_options($includeinherit, $includenotset);
629
 
630
        // Extract the options.
631
        $return = (object) external_api::clean_returnvalue(external::get_category_options_returns(), $result);
632
        $options = $return->options;
633
 
634
        // Make sure everything checks out.
635
        $this->assertCount(count($expectedoptions), $options);
636
        foreach ($options as $option) {
637
            $this->assertContains($option, $expectedoptions);
638
        }
639
    }
640
 
641
    /**
642
     * Test for \tool_dataprivacy\external::get_purpose_options()
643
     * when called by a user that doesn't have the manage registry capability.
644
     */
11 efrain 645
    public function test_get_purpose_options_no_capability(): void {
1 efrain 646
        $this->resetAfterTest();
647
        $generator = $this->getDataGenerator();
648
        $user = $generator->create_user();
649
        $this->setUser($user);
650
        $this->expectException(\required_capability_exception::class);
651
        external::get_category_options(true, true);
652
    }
653
 
654
    /**
655
     * Test for \tool_dataprivacy\external::get_purpose_options().
656
     *
657
     * @dataProvider get_options_provider
658
     * @param bool $includeinherit Whether "Inherit" would be included to the options.
659
     * @param bool $includenotset Whether "Not set" would be included to the options.
660
     */
11 efrain 661
    public function test_get_purpose_options($includeinherit, $includenotset): void {
1 efrain 662
        $this->resetAfterTest();
663
        $this->setAdminUser();
664
 
665
        // Prepare our expected options.
666
        $expectedoptions = [];
667
        if ($includeinherit) {
668
            $expectedoptions[] = [
669
                'id' => context_instance::INHERIT,
670
                'name' => get_string('inherit', 'tool_dataprivacy'),
671
            ];
672
        }
673
 
674
        if ($includenotset) {
675
            $expectedoptions[] = [
676
                'id' => context_instance::NOTSET,
677
                'name' => get_string('notset', 'tool_dataprivacy'),
678
            ];
679
        }
680
 
681
        for ($i = 1; $i <= 3; $i++) {
682
            $purpose = api::create_purpose((object)[
683
                'name' => 'Purpose ' . $i, 'retentionperiod' => 'PT1M', 'lawfulbases' => 'gdpr_art_6_1_a'
684
            ]);
685
            $expectedoptions[] = [
686
                'id' => $purpose->get('id'),
687
                'name' => $purpose->get('name'),
688
            ];
689
        }
690
 
691
        // Call the WS function.
692
        $result = external::get_purpose_options($includeinherit, $includenotset);
693
 
694
        // Extract the options.
695
        $return = (object) external_api::clean_returnvalue(external::get_purpose_options_returns(), $result);
696
        $options = $return->options;
697
 
698
        // Make sure everything checks out.
699
        $this->assertCount(count($expectedoptions), $options);
700
        foreach ($options as $option) {
701
            $this->assertContains($option, $expectedoptions);
702
        }
703
    }
704
 
705
    /**
706
     * Data provider for \tool_dataprivacy_external_testcase::get_activity_options().
707
     */
708
    public function get_activity_options_provider() {
709
        return [
710
            [false, false, true],
711
            [false, true, true],
712
            [true, false, true],
713
            [true, true, true],
714
            [false, false, false],
715
            [false, true, false],
716
            [true, false, false],
717
            [true, true, false],
718
        ];
719
    }
720
 
721
    /**
722
     * Test for \tool_dataprivacy\external::get_activity_options().
723
     *
724
     * @dataProvider get_activity_options_provider
725
     * @param bool $inheritcategory Whether the category would be set to "Inherit".
726
     * @param bool $inheritpurpose Whether the purpose would be set to "Inherit".
727
     * @param bool $nodefaults Whether to fetch only activities that don't have defaults.
728
     */
11 efrain 729
    public function test_get_activity_options($inheritcategory, $inheritpurpose, $nodefaults): void {
1 efrain 730
        $this->resetAfterTest();
731
        $this->setAdminUser();
732
 
733
        $category = api::create_category((object)['name' => 'Test category']);
734
        $purpose = api::create_purpose((object)[
735
            'name' => 'Test purpose ', 'retentionperiod' => 'PT1M', 'lawfulbases' => 'gdpr_art_6_1_a'
736
        ]);
737
        $categoryid = $category->get('id');
738
        $purposeid = $purpose->get('id');
739
 
740
        if ($inheritcategory) {
741
            $categoryid = context_instance::INHERIT;
742
        }
743
        if ($inheritpurpose) {
744
            $purposeid = context_instance::INHERIT;
745
        }
746
 
747
        // Set the context default for the assignment module.
748
        api::set_context_defaults(CONTEXT_MODULE, $categoryid, $purposeid, 'assign');
749
 
750
        // Call the WS function.
751
        $result = external::get_activity_options($nodefaults);
752
 
753
        // Extract the options.
754
        $return = (object) external_api::clean_returnvalue(external::get_activity_options_returns(), $result);
755
        $options = $return->options;
756
 
757
        // Make sure the options list is not empty.
758
        $this->assertNotEmpty($options);
759
 
760
        $pluginwithdefaults = [
761
            'name' => 'assign',
762
            'displayname' => get_string('pluginname', 'assign')
763
        ];
764
 
765
        // If we don't want plugins with defaults to be listed or if both of the category and purpose are set to inherit,
766
        // the assign module should be listed.
767
        if (!$nodefaults || ($inheritcategory && $inheritpurpose)) {
768
            $this->assertContains($pluginwithdefaults, $options);
769
        } else {
770
            $this->assertNotContains($pluginwithdefaults, $options);
771
        }
772
    }
773
 
774
    /**
775
     * Test for external::bulk_approve_data_requests().
776
     */
11 efrain 777
    public function test_bulk_approve_data_requests(): void {
1 efrain 778
        $this->resetAfterTest();
779
 
780
        // Create delete data requests.
781
        $requester1 = $this->getDataGenerator()->create_user();
782
        $this->setUser($requester1->id);
783
        $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
784
        $requestid1 = $datarequest1->get('id');
785
 
786
        $requester2 = $this->getDataGenerator()->create_user();
787
        $this->setUser($requester2->id);
788
        $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
789
        $requestid2 = $datarequest2->get('id');
790
 
791
        // Approve the requests.
792
        $this->setAdminUser();
793
        api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
794
        api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
795
        $result = external::bulk_approve_data_requests([$requestid1, $requestid2]);
796
 
797
        $return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
798
        $this->assertTrue($return->result);
799
        $this->assertEmpty($return->warnings);
800
    }
801
 
802
    /**
803
     * Test for external::bulk_approve_data_requests() for a non-existent request ID.
804
     */
11 efrain 805
    public function test_bulk_approve_data_requests_non_existent(): void {
1 efrain 806
        $this->resetAfterTest();
807
 
808
        $this->setAdminUser();
809
 
810
        $result = external::bulk_approve_data_requests([42]);
811
 
812
        $return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
813
        $this->assertFalse($return->result);
814
        $this->assertCount(1, $return->warnings);
815
        $warning = reset($return->warnings);
816
        $this->assertEquals('errorrequestnotfound', $warning['warningcode']);
817
        $this->assertEquals(42, $warning['item']);
818
    }
819
 
820
    /**
821
     * Test for external::bulk_deny_data_requests() for a user without permission to deny requests.
822
     */
11 efrain 823
    public function test_bulk_approve_data_requests_no_permission(): void {
1 efrain 824
        $this->resetAfterTest();
825
 
826
        // Create delete data requests.
827
        $requester1 = $this->getDataGenerator()->create_user();
828
        $this->setUser($requester1->id);
829
        $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
830
        $requestid1 = $datarequest1->get('id');
831
 
832
        $requester2 = $this->getDataGenerator()->create_user();
833
        $this->setUser($requester2->id);
834
        $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
835
        $requestid2 = $datarequest2->get('id');
836
 
837
        $this->setAdminUser();
838
        api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
839
        api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
840
 
841
        // Approve the requests.
842
        $uut = $this->getDataGenerator()->create_user();
843
        $this->setUser($uut);
844
 
845
        $this->expectException(\required_capability_exception::class);
846
        $result = external::bulk_approve_data_requests([$requestid1, $requestid2]);
847
    }
848
 
849
    /**
850
     * Test for external::bulk_deny_data_requests() for a user without permission to deny requests.
851
     */
11 efrain 852
    public function test_bulk_approve_data_requests_own_request(): void {
1 efrain 853
        $this->resetAfterTest();
854
 
855
        // Create delete data requests.
856
        $requester1 = $this->getDataGenerator()->create_user();
857
        $this->setUser($requester1->id);
858
        $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
859
        $requestid1 = $datarequest1->get('id');
860
 
861
        $requester2 = $this->getDataGenerator()->create_user();
862
        $this->setUser($requester2->id);
863
        $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
864
        $requestid2 = $datarequest2->get('id');
865
 
866
        $this->setAdminUser();
867
        api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
868
        api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
869
 
870
        // Deny the requests.
871
        $this->setUser($requester1);
872
 
873
        $this->expectException(\required_capability_exception::class);
874
        $result = external::bulk_approve_data_requests([$requestid1]);
875
    }
876
 
877
    /**
878
     * Test for external::bulk_deny_data_requests().
879
     */
11 efrain 880
    public function test_bulk_deny_data_requests(): void {
1 efrain 881
        $this->resetAfterTest();
882
 
883
        // Create delete data requests.
884
        $requester1 = $this->getDataGenerator()->create_user();
885
        $this->setUser($requester1->id);
886
        $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
887
        $requestid1 = $datarequest1->get('id');
888
 
889
        $requester2 = $this->getDataGenerator()->create_user();
890
        $this->setUser($requester2->id);
891
        $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
892
        $requestid2 = $datarequest2->get('id');
893
 
894
        // Deny the requests.
895
        $this->setAdminUser();
896
        api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
897
        api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
898
        $result = external::bulk_deny_data_requests([$requestid1, $requestid2]);
899
 
900
        $return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
901
        $this->assertTrue($return->result);
902
        $this->assertEmpty($return->warnings);
903
    }
904
 
905
    /**
906
     * Test for external::bulk_deny_data_requests() for a non-existent request ID.
907
     */
11 efrain 908
    public function test_bulk_deny_data_requests_non_existent(): void {
1 efrain 909
        $this->resetAfterTest();
910
 
911
        $this->setAdminUser();
912
        $result = external::bulk_deny_data_requests([42]);
913
        $return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
914
 
915
        $this->assertFalse($return->result);
916
        $this->assertCount(1, $return->warnings);
917
        $warning = reset($return->warnings);
918
        $this->assertEquals('errorrequestnotfound', $warning['warningcode']);
919
        $this->assertEquals(42, $warning['item']);
920
    }
921
 
922
    /**
923
     * Test for external::bulk_deny_data_requests() for a user without permission to deny requests.
924
     */
11 efrain 925
    public function test_bulk_deny_data_requests_no_permission(): void {
1 efrain 926
        $this->resetAfterTest();
927
 
928
        // Create delete data requests.
929
        $requester1 = $this->getDataGenerator()->create_user();
930
        $this->setUser($requester1->id);
931
        $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
932
        $requestid1 = $datarequest1->get('id');
933
 
934
        $requester2 = $this->getDataGenerator()->create_user();
935
        $this->setUser($requester2->id);
936
        $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
937
        $requestid2 = $datarequest2->get('id');
938
 
939
        $this->setAdminUser();
940
        api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
941
        api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
942
 
943
        // Deny the requests.
944
        $uut = $this->getDataGenerator()->create_user();
945
        $this->setUser($uut);
946
 
947
        $this->expectException(\required_capability_exception::class);
948
        $result = external::bulk_deny_data_requests([$requestid1, $requestid2]);
949
    }
950
 
951
    /**
952
     * Test for external::bulk_deny_data_requests() for a user cannot approve their own request.
953
     */
11 efrain 954
    public function test_bulk_deny_data_requests_own_request(): void {
1 efrain 955
        $this->resetAfterTest();
956
 
957
        // Create delete data requests.
958
        $requester1 = $this->getDataGenerator()->create_user();
959
        $this->setUser($requester1->id);
960
        $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
961
        $requestid1 = $datarequest1->get('id');
962
 
963
        $requester2 = $this->getDataGenerator()->create_user();
964
        $this->setUser($requester2->id);
965
        $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
966
        $requestid2 = $datarequest2->get('id');
967
 
968
        $this->setAdminUser();
969
        api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
970
        api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
971
 
972
        // Deny the requests.
973
        $this->setUser($requester1);
974
 
975
        $this->expectException(\required_capability_exception::class);
976
        $result = external::bulk_deny_data_requests([$requestid1]);
977
    }
978
 
979
    /**
980
     * Test for external::get_users(), case search using non-identity field without
981
     * facing any permission problem.
982
     *
983
     * @throws coding_exception
984
     * @throws dml_exception
985
     * @throws invalid_parameter_exception
986
     * @throws required_capability_exception
987
     * @throws restricted_context_exception
988
     */
11 efrain 989
    public function test_get_users_using_using_non_identity(): void {
1 efrain 990
        $this->resetAfterTest();
991
        $context = \context_system::instance();
992
        $requester = $this->getDataGenerator()->create_user();
993
        $role = $this->getDataGenerator()->create_role();
994
        role_assign($role, $requester->id, $context);
995
        assign_capability('tool/dataprivacy:managedatarequests', CAP_ALLOW, $role, $context);
996
        $this->setUser($requester);
997
 
998
        $this->getDataGenerator()->create_user([
999
            'firstname' => 'First Student'
1000
        ]);
1001
        $student2 = $this->getDataGenerator()->create_user([
1002
            'firstname' => 'Second Student'
1003
        ]);
1004
 
1005
        $results = external::get_users('Second');
1006
        $this->assertCount(1, $results);
1007
        $this->assertEquals((object)[
1008
            'id' => $student2->id,
1009
            'fullname' => fullname($student2),
1010
            'extrafields' => []
1011
        ], $results[$student2->id]);
1012
    }
1013
 
1014
    /**
1015
     * Test for external::get_users(), case search using identity field but
1016
     * don't have "moodle/site:viewuseridentity" permission.
1017
     *
1018
     * @throws coding_exception
1019
     * @throws dml_exception
1020
     * @throws invalid_parameter_exception
1021
     * @throws required_capability_exception
1022
     * @throws restricted_context_exception
1023
     */
11 efrain 1024
    public function test_get_users_using_identity_without_permission(): void {
1 efrain 1025
        global $CFG;
1026
 
1027
        $this->resetAfterTest();
1028
        $CFG->showuseridentity = 'institution';
1029
 
1030
        // Create requester user and assign correct capability.
1031
        $context = \context_system::instance();
1032
        $requester = $this->getDataGenerator()->create_user();
1033
        $role = $this->getDataGenerator()->create_role();
1034
        role_assign($role, $requester->id, $context);
1035
        assign_capability('tool/dataprivacy:managedatarequests', CAP_ALLOW, $role, $context);
1036
        $this->setUser($requester);
1037
 
1038
        $this->getDataGenerator()->create_user([
1039
            'institution' => 'University1'
1040
        ]);
1041
 
1042
        $results = external::get_users('University1');
1043
        $this->assertEmpty($results);
1044
    }
1045
 
1046
    /**
1047
     * Test for external::get_users(), case search using disabled identity field
1048
     * even they have "moodle/site:viewuseridentity" permission.
1049
     *
1050
     * @throws coding_exception
1051
     * @throws dml_exception
1052
     * @throws invalid_parameter_exception
1053
     * @throws required_capability_exception
1054
     * @throws restricted_context_exception
1055
     */
11 efrain 1056
    public function test_get_users_using_field_not_in_identity(): void {
1 efrain 1057
        $this->resetAfterTest();
1058
 
1059
        $context = \context_system::instance();
1060
        $requester = $this->getDataGenerator()->create_user();
1061
        $role = $this->getDataGenerator()->create_role();
1062
        role_assign($role, $requester->id, $context);
1063
        assign_capability('tool/dataprivacy:managedatarequests', CAP_ALLOW, $role, $context);
1064
        assign_capability('moodle/site:viewuseridentity', CAP_ALLOW, $role, $context);
1065
        $this->setUser($requester);
1066
 
1067
        $this->getDataGenerator()->create_user([
1068
            'institution' => 'University1'
1069
        ]);
1070
 
1071
        $results = external::get_users('University1');
1072
        $this->assertEmpty($results);
1073
    }
1074
 
1075
    /**
1076
     * Test for external::get_users(), case search using enabled identity field
1077
     * with "moodle/site:viewuseridentity" permission.
1078
     *
1079
     * @throws coding_exception
1080
     * @throws dml_exception
1081
     * @throws invalid_parameter_exception
1082
     * @throws required_capability_exception
1083
     * @throws restricted_context_exception
1084
     */
11 efrain 1085
    public function test_get_users(): void {
1 efrain 1086
        global $CFG;
1087
        $this->resetAfterTest();
1088
        $CFG->showuseridentity = 'institution';
1089
        $context = \context_system::instance();
1090
        $requester = $this->getDataGenerator()->create_user();
1091
        $role = $this->getDataGenerator()->create_role();
1092
        role_assign($role, $requester->id, $context);
1093
        assign_capability('tool/dataprivacy:managedatarequests', CAP_ALLOW, $role, $context);
1094
        assign_capability('moodle/site:viewuseridentity', CAP_ALLOW, $role, $context);
1095
        $this->setUser($requester);
1096
 
1097
        $student1 = $this->getDataGenerator()->create_user([
1098
            'institution' => 'University1'
1099
        ]);
1100
        $this->getDataGenerator()->create_user([
1101
            'institution' => 'University2'
1102
        ]);
1103
 
1104
        $results = external::get_users('University1');
1105
        $this->assertCount(1, $results);
1106
        $this->assertEquals((object)[
1107
            'id' => $student1->id,
1108
            'fullname' => fullname($student1),
1109
            'extrafields' => [
1110
 
1111
                    'name' => 'institution',
1112
                    'value' => 'University1'
1113
                ]
1114
            ]
1115
        ], $results[$student1->id]);
1116
    }
1117
 
1118
    /**
1119
     * Test for external::get_access_information().
1120
     */
11 efrain 1121
    public function test_get_access_information(): void {
1 efrain 1122
        $this->resetAfterTest();
1123
 
1124
        $this->setAdminUser();
1125
        $result = get_access_information::execute();
1126
        $result = external_api::clean_returnvalue(get_access_information::execute_returns(), $result);
1127
        $this->assertFalse($result['cancontactdpo']);   // Disabled by default.
1128
 
1129
        // Enable contact DPO.
1130
        set_config('contactdataprotectionofficer', 1, 'tool_dataprivacy');
1131
 
1132
        $user = $this->getDataGenerator()->create_user();
1133
        $this->setUser($user);
1134
        $result = get_access_information::execute();
1135
        $result = external_api::clean_returnvalue(get_access_information::execute_returns(), $result);
1136
 
1137
        $this->assertTrue($result['cancontactdpo']);
1138
        $this->assertTrue($result['cancreatedatadownloadrequest']);
1139
        $this->assertTrue($result['cancreatedatadeletionrequest']);
1140
        $this->assertFalse($result['canmanagedatarequests']);
1141
        $this->assertFalse($result['hasongoingdatadownloadrequest']);
1142
        $this->assertFalse($result['hasongoingdatadeletionrequest']);
1143
    }
1144
 
1145
    /**
1146
     * Test for external::create_data_request()
1147
     */
11 efrain 1148
    public function test_create_data_request(): void {
1 efrain 1149
        $this->resetAfterTest();
1150
 
1151
        $systemcontext = \context_system::instance();
1152
        $user = $this->getDataGenerator()->create_user();
1153
        $requester = $this->getDataGenerator()->create_user();
1154
        $role = $this->getDataGenerator()->create_role();
1155
        assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $role, $systemcontext);
1156
        role_assign($role, $requester->id, \context_user::instance($user->id));
1157
 
1158
        // Enable contact DPO.
1159
        set_config('contactdataprotectionofficer', 1, 'tool_dataprivacy');
1160
 
1161
        // Create a data request for myself.
1162
        $this->setUser($user);
1163
        $comment = 'Example comment';
1164
        $result = create_data_request::execute(api::DATAREQUEST_TYPE_DELETE, $comment);
1165
        $result = external_api::clean_returnvalue(create_data_request::execute_returns(), $result);
1166
 
1167
        $this->assertEmpty($result['warnings']);
1168
 
1169
        $requests = api::get_data_requests($user->id);
1170
        $this->assertCount(1, $requests);
1171
        $request = reset($requests);
1172
        $this->assertEquals($result['datarequestid'], $request->get('id'));
1173
        $this->assertEquals($user->id, $request->get('userid'));
1174
        $this->assertEquals(api::DATAREQUEST_TYPE_DELETE, $request->get('type'));
1175
        $this->assertEquals($comment, $request->get('comments'));
1176
 
1177
        // Create on behalf of other user a different type of request.
1178
        $this->setUser($requester);
1179
        $comment = 'Example comment';
1180
        $result = create_data_request::execute(api::DATAREQUEST_TYPE_EXPORT, $comment, $user->id);
1181
        $result = external_api::clean_returnvalue(create_data_request::execute_returns(), $result);
1182
 
1183
        $this->assertEmpty($result['warnings']);
1184
 
1185
        $requests = api::get_data_requests($user->id);
1186
        $this->assertCount(2, $requests);
1187
        foreach ($requests as $request) {
1188
            if ($request->get('type') == api::DATAREQUEST_TYPE_EXPORT) {
1189
                $this->assertEquals($result['datarequestid'], $request->get('id'));
1190
                $this->assertEquals($user->id, $request->get('userid'));
1191
                $this->assertEquals($comment, $request->get('comments'));
1192
            } else {
1193
                $this->assertEquals($user->id, $request->get('userid'));
1194
                $this->assertEquals(api::DATAREQUEST_TYPE_DELETE, $request->get('type'));
1195
                $this->assertEquals('Example comment', $request->get('comments'));
1196
            }
1197
        }
1198
    }
1199
 
1200
    /**
1201
     * Test for external::create_data_request() when no dpo available.
1202
     */
11 efrain 1203
    public function test_create_data_request_no_dpo(): void {
1 efrain 1204
        $this->resetAfterTest();
1205
 
1206
        $user = $this->getDataGenerator()->create_user();
1207
        $this->setUser($user);
1208
 
1209
        $this->expectException(\moodle_exception::class);
1210
        $this->expectExceptionMessage(get_string('contactdpoviaprivacypolicy', 'tool_dataprivacy'));
1211
        create_data_request::execute(api::DATAREQUEST_TYPE_DELETE, 'Example comment');
1212
    }
1213
 
1214
    /**
1215
     * Test for external::create_data_request() with missing permission.
1216
     */
11 efrain 1217
    public function test_create_data_request_no_permission(): void {
1 efrain 1218
        $this->resetAfterTest();
1219
 
1220
        // Enable contact DPO.
1221
        set_config('contactdataprotectionofficer', 1, 'tool_dataprivacy');
1222
 
1223
        $user = $this->getDataGenerator()->create_user();
1224
        $anotheruser = $this->getDataGenerator()->create_user();
1225
        $this->setUser($user);
1226
 
1227
        $this->expectException(\required_capability_exception::class);
1228
        create_data_request::execute(api::DATAREQUEST_TYPE_DELETE, 'Example comment', $anotheruser->id);
1229
    }
1230
 
1231
    /**
1232
     * Test for external::create_data_request() with invalid request type.
1233
     */
11 efrain 1234
    public function test_create_data_request_invalid_type(): void {
1 efrain 1235
        $this->resetAfterTest();
1236
 
1237
        // Enable contact DPO.
1238
        set_config('contactdataprotectionofficer', 1, 'tool_dataprivacy');
1239
 
1240
        $user = $this->getDataGenerator()->create_user();
1241
        $this->setUser($user);
1242
 
1243
        $this->expectException(\moodle_exception::class);
1244
        $this->expectExceptionMessage(get_string('errorinvalidrequesttype', 'tool_dataprivacy'));
1245
        create_data_request::execute(125, 'Example comment');
1246
    }
1247
 
1248
    /**
1249
     * Test for external::get_data_requests().
1250
     */
11 efrain 1251
    public function test_get_data_requests(): void {
1 efrain 1252
        global $DB;
1253
 
1254
        $this->resetAfterTest();
1255
 
1256
        $user = $this->getDataGenerator()->create_user();
1257
        $anotheruser = $this->getDataGenerator()->create_user();
1258
        $this->setUser($user);
1259
 
1260
        // Empty results.
1261
        $result = get_data_requests::execute($user->id);
1262
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1263
 
1264
        $this->assertEmpty($result['warnings']);
1265
        $this->assertEmpty($result['requests']);
1266
 
1267
        // Create data requests.
1268
        $comment = 'Example comment';
1269
        $request1 = api::create_data_request($user->id, api::DATAREQUEST_TYPE_DELETE, $comment);
1270
        $request2 = api::create_data_request($user->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
1271
        $request3 = api::create_data_request($anotheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment,
1272
            data_request::DATAREQUEST_CREATION_AUTO);
1273
 
1274
        // Get data requests.
1275
        $result = get_data_requests::execute($user->id);
1276
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1277
 
1278
        $this->assertEmpty($result['warnings']);
1279
        $this->assertCount(2, $result['requests']);
1280
        foreach ($result['requests'] as $request) {
1281
            if ($request['id'] == $request1->get('id')) {
1282
                $this->assertEquals($user->id, $request['userid']);
1283
                $this->assertEquals(api::DATAREQUEST_TYPE_DELETE, $request['type']);
1284
                $this->assertEquals($comment, $request['comments']);
1285
            } else {
1286
                $this->assertEquals($user->id, $request['userid']);
1287
                $this->assertEquals(api::DATAREQUEST_TYPE_EXPORT, $request['type']);
1288
                $this->assertEquals($comment, $request['comments']);
1289
            }
1290
            $this->assertArrayNotHasKey('downloadlink', $request);  // Download link only present for download ready requests.
1291
        }
1292
 
1293
        // Filter by type.
1294
        $result = get_data_requests::execute($user->id, [], [api::DATAREQUEST_TYPE_DELETE]);
1295
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1296
        $this->assertCount(1, $result['requests']);
1297
        $this->assertEquals($request1->get('id'), $result['requests'][0]['id']);
1298
 
1299
        // Admin get all.
1300
        $this->setAdminUser();
1301
        $result = get_data_requests::execute();
1302
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1303
 
1304
        $this->assertCount(3, $result['requests']);
1305
 
1306
        // Test limit.
1307
        $result = get_data_requests::execute(0, [], [], [], '', 2, 1);
1308
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1309
 
1310
        $this->assertCount(1, $result['requests']);
1311
 
1312
        // Test sort.
1313
        $result = get_data_requests::execute(0, [], [], [], 'id DESC');
1314
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1315
        $this->assertEquals($request1->get('id'), $result['requests'][2]['id']);
1316
        $this->assertEquals($request2->get('id'), $result['requests'][1]['id']);
1317
        $this->assertEquals($request3->get('id'), $result['requests'][0]['id']);
1318
 
1319
        // Test filter by status.
1320
        api::update_request_status($request3->get('id'), api::DATAREQUEST_STATUS_DOWNLOAD_READY);
1321
        $result = get_data_requests::execute(0, [api::DATAREQUEST_STATUS_DOWNLOAD_READY]);
1322
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1323
 
1324
        $this->assertCount(1, $result['requests']);
1325
        $this->assertEquals($request3->get('id'), $result['requests'][0]['id']);
1326
        // Check download link because the download is now ready.
1327
        $usercontext = \context_user::instance($anotheruser->id, IGNORE_MISSING);
1328
        $downloadlink = api::get_download_link($usercontext, $result['requests'][0]['id'])->url;
1329
        $this->assertEquals($downloadlink->out(false), $result['requests'][0]['downloadlink']);
1330
 
1331
        // Test filter by creation method.
1332
        $result = get_data_requests::execute(0, [], [], [data_request::DATAREQUEST_CREATION_AUTO]);
1333
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1334
 
1335
        $this->assertCount(1, $result['requests']);
1336
        $this->assertEquals($request3->get('id'), $result['requests'][0]['id']);
1337
 
1338
        // Get data requests for another user without required permissions.
1339
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user'], MUST_EXIST);
1340
        assign_capability('tool/dataprivacy:downloadownrequest', CAP_PROHIBIT, $userrole, \context_user::instance($anotheruser->id));
1341
 
1342
        $this->setUser($anotheruser);
1343
        // Get my data request ready for download but without permissons for download it.
1344
        $result = get_data_requests::execute($anotheruser->id, [api::DATAREQUEST_STATUS_DOWNLOAD_READY]);
1345
        $result = external_api::clean_returnvalue(get_data_requests::execute_returns(), $result);
1346
        $this->assertArrayNotHasKey('downloadlink', $result['requests'][0]);   // Download link is not present.
1347
 
1348
        // And now try to see a different user requests.
1349
        $this->expectException(\moodle_exception::class);
1350
        $dponamestring = implode (', ', api::get_dpo_role_names());
1351
        $this->expectExceptionMessage(get_string('privacyofficeronly', 'tool_dataprivacy', $dponamestring));
1352
        $result = get_data_requests::execute($user->id);
1353
    }
1354
 
1355
    /**
1356
     * Test for external::get_data_requests() invalid user id.
1357
     */
11 efrain 1358
    public function test_get_data_requests_invalid_userid(): void {
1 efrain 1359
        $this->resetAfterTest();
1360
        $this->setAdminUser();
1361
 
1362
        $this->expectException(\dml_exception::class);
1363
        get_data_requests::execute(-1);
1364
    }
1365
}