MDL-63702 core_block: Update to use new userlist interface.
[moodle.git] / blocks / tests / privacy_test.php
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/>.
17 /**
18  * Data provider tests.
19  *
20  * @package    core_block
21  * @category   test
22  * @copyright  2018 Frédéric Massart
23  * @author     Frédéric Massart <fred@branchup.tech>
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
27 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
30 use core_privacy\tests\provider_testcase;
31 use core_privacy\local\request\approved_contextlist;
32 use core_privacy\local\request\transform;
33 use core_privacy\local\request\writer;
34 use core_block\privacy\provider;
36 /**
37  * Data provider testcase class.
38  *
39  * @package    core_block
40  * @category   test
41  * @copyright  2018 Frédéric Massart
42  * @author     Frédéric Massart <fred@branchup.tech>
43  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44  */
45 class core_block_privacy_testcase extends provider_testcase {
47     public function setUp() {
48         $this->resetAfterTest();
49     }
51     public function test_get_contexts_for_userid() {
52         $dg = $this->getDataGenerator();
53         $c1 = $dg->create_course();
54         $c2 = $dg->create_course();
55         $u1 = $dg->create_user();
56         $u2 = $dg->create_user();
57         $c1ctx = context_course::instance($c1->id);
58         $c2ctx = context_course::instance($c2->id);
59         $u1ctx = context_user::instance($u1->id);
60         $u2ctx = context_user::instance($u2->id);
62         $manager = $this->get_block_manager(['region-a'], $c1ctx);
63         $manager->add_block('myprofile', 'region-a', 0, false);
64         $manager->load_blocks();
65         $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
67         $manager = $this->get_block_manager(['region-a'], $c2ctx);
68         $manager->add_block('login', 'region-a', 0, false);
69         $manager->add_block('mentees', 'region-a', 1, false);
70         $manager->load_blocks();
71         list($blocklogin, $blockmentees) = $manager->get_blocks_for_region('region-a');
73         $manager = $this->get_block_manager(['region-a'], $u1ctx);
74         $manager->add_block('private_files', 'region-a', 0, false);
75         $manager->load_blocks();
76         $blockprivatefiles = $manager->get_blocks_for_region('region-a')[0];
78         $this->set_hidden_pref($blocklogin, true, $u1->id);
79         $this->set_hidden_pref($blockprivatefiles, true, $u1->id);
80         $this->set_docked_pref($blockmyprofile, true, $u1->id);
81         $this->set_docked_pref($blockmentees, true, $u1->id);
82         $this->set_docked_pref($blockmentees, true, $u2->id);
84         $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
85         $this->assertCount(4, $contextids);
86         $this->assertTrue(in_array($blocklogin->context->id, $contextids));
87         $this->assertTrue(in_array($blockprivatefiles->context->id, $contextids));
88         $this->assertTrue(in_array($blockmyprofile->context->id, $contextids));
89         $this->assertTrue(in_array($blockmentees->context->id, $contextids));
91         $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
92         $this->assertCount(1, $contextids);
93         $this->assertTrue(in_array($blockmentees->context->id, $contextids));
94     }
96     /**
97      * Test that user IDs are returned for a given context.
98      */
99     public function test_get_users_in_context() {
100         global $DB;
101         $u1 = $this->getDataGenerator()->create_user();
102         $u2 = $this->getDataGenerator()->create_user();
103         $u3 = $this->getDataGenerator()->create_user();
105         $course = $this->getDataGenerator()->create_course();
107         $manager = $this->get_block_manager(['region-a'], context_course::instance($course->id));
108         $manager->add_block('myprofile', 'region-a', 0, false);
109         $manager->load_blocks();
110         $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
112         $this->set_hidden_pref($blockmyprofile, true, $u1->id);
113         $this->set_hidden_pref($blockmyprofile, true, $u3->id);
114         $this->set_docked_pref($blockmyprofile, true, $u2->id);
115         $this->set_docked_pref($blockmyprofile, true, $u3->id);
117         $records = $DB->get_records('block_instances', ['blockname' => 'myprofile']);
118         $record = array_shift($records);
119         $blockcontext = context_block::instance($record->id);
121         $userlist = new \core_privacy\local\request\userlist($blockcontext, 'core_block');
122         provider::get_users_in_context($userlist);
123         $this->assertCount(3, $userlist->get_userids());
124     }
127     public function test_delete_data_for_user() {
128         global $DB;
129         $dg = $this->getDataGenerator();
130         $c1 = $dg->create_course();
131         $c2 = $dg->create_course();
132         $u1 = $dg->create_user();
133         $u2 = $dg->create_user();
134         $c1ctx = context_course::instance($c1->id);
135         $c2ctx = context_course::instance($c2->id);
136         $u1ctx = context_user::instance($u1->id);
137         $u2ctx = context_user::instance($u2->id);
139         $manager = $this->get_block_manager(['region-a'], $c1ctx);
140         $manager->add_block('myprofile', 'region-a', 0, false);
141         $manager->load_blocks();
142         $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
144         $manager = $this->get_block_manager(['region-a'], $c2ctx);
145         $manager->add_block('login', 'region-a', 0, false);
146         $manager->add_block('mentees', 'region-a', 1, false);
147         $manager->load_blocks();
148         list($blocklogin, $blockmentees) = $manager->get_blocks_for_region('region-a');
150         $manager = $this->get_block_manager(['region-a'], $u1ctx);
151         $manager->add_block('private_files', 'region-a', 0, false);
152         $manager->load_blocks();
153         $blockprivatefiles = $manager->get_blocks_for_region('region-a')[0];
155         $this->set_hidden_pref($blocklogin, true, $u1->id);
156         $this->set_hidden_pref($blocklogin, true, $u2->id);
157         $this->set_hidden_pref($blockprivatefiles, true, $u1->id);
158         $this->set_hidden_pref($blockmyprofile, true, $u1->id);
159         $this->set_docked_pref($blockmyprofile, true, $u1->id);
160         $this->set_docked_pref($blockmentees, true, $u1->id);
161         $this->set_docked_pref($blockmentees, true, $u2->id);
163         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
164             'name' => "block{$blocklogin->instance->id}hidden"]));
165         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
166             'name' => "block{$blocklogin->instance->id}hidden"]));
167         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
168             'name' => "block{$blockprivatefiles->instance->id}hidden"]));
169         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
170             'name' => "block{$blockmyprofile->instance->id}hidden"]));
171         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
172             'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
173         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
174             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
175         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
176             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
178         provider::delete_data_for_user(new approved_contextlist($u1, 'core_block', [$blocklogin->context->id,
179             $blockmyprofile->context->id, $blockmentees->context->id]));
181         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
182             'name' => "block{$blocklogin->instance->id}hidden"]));
183         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
184             'name' => "block{$blocklogin->instance->id}hidden"]));
185         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
186             'name' => "block{$blockprivatefiles->instance->id}hidden"]));
187         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
188             'name' => "block{$blockmyprofile->instance->id}hidden"]));
189         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
190             'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
191         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
192             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
193         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
194             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
195     }
197     public function test_delete_data_for_all_users_in_context() {
198         global $DB;
199         $dg = $this->getDataGenerator();
200         $c1 = $dg->create_course();
201         $c2 = $dg->create_course();
202         $u1 = $dg->create_user();
203         $u2 = $dg->create_user();
204         $c1ctx = context_course::instance($c1->id);
205         $c2ctx = context_course::instance($c2->id);
206         $u1ctx = context_user::instance($u1->id);
207         $u2ctx = context_user::instance($u2->id);
209         $manager = $this->get_block_manager(['region-a'], $c1ctx);
210         $manager->add_block('myprofile', 'region-a', 0, false);
211         $manager->load_blocks();
212         $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
214         $manager = $this->get_block_manager(['region-a'], $c2ctx);
215         $manager->add_block('login', 'region-a', 0, false);
216         $manager->add_block('mentees', 'region-a', 1, false);
217         $manager->load_blocks();
218         list($blocklogin, $blockmentees) = $manager->get_blocks_for_region('region-a');
220         $manager = $this->get_block_manager(['region-a'], $u1ctx);
221         $manager->add_block('private_files', 'region-a', 0, false);
222         $manager->load_blocks();
223         $blockprivatefiles = $manager->get_blocks_for_region('region-a')[0];
225         $this->set_hidden_pref($blocklogin, true, $u1->id);
226         $this->set_hidden_pref($blocklogin, true, $u2->id);
227         $this->set_hidden_pref($blockprivatefiles, true, $u1->id);
228         $this->set_hidden_pref($blockmyprofile, true, $u1->id);
229         $this->set_docked_pref($blockmyprofile, true, $u1->id);
230         $this->set_docked_pref($blockmentees, true, $u1->id);
231         $this->set_docked_pref($blockmentees, true, $u2->id);
233         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
234             'name' => "block{$blocklogin->instance->id}hidden"]));
235         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
236             'name' => "block{$blocklogin->instance->id}hidden"]));
237         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
238             'name' => "block{$blockprivatefiles->instance->id}hidden"]));
239         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
240             'name' => "block{$blockmyprofile->instance->id}hidden"]));
241         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
242             'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
243         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
244             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
245         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
246             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
248         // Nothing happens.
249         provider::delete_data_for_all_users_in_context($c1ctx);
250         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
251             'name' => "block{$blocklogin->instance->id}hidden"]));
252         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
253             'name' => "block{$blocklogin->instance->id}hidden"]));
254         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
255             'name' => "block{$blockprivatefiles->instance->id}hidden"]));
256         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
257             'name' => "block{$blockmyprofile->instance->id}hidden"]));
258         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
259             'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
260         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
261             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
262         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
263             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
265         // Delete one block.
266         provider::delete_data_for_all_users_in_context($blocklogin->context);
267         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
268             'name' => "block{$blocklogin->instance->id}hidden"]));
269         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u2->id,
270             'name' => "block{$blocklogin->instance->id}hidden"]));
271         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
272             'name' => "block{$blockprivatefiles->instance->id}hidden"]));
273         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
274             'name' => "block{$blockmyprofile->instance->id}hidden"]));
275         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
276             'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
277         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
278             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
279         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
280             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
282         // Delete another block.
283         provider::delete_data_for_all_users_in_context($blockmyprofile->context);
284         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
285             'name' => "block{$blocklogin->instance->id}hidden"]));
286         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u2->id,
287             'name' => "block{$blocklogin->instance->id}hidden"]));
288         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
289             'name' => "block{$blockprivatefiles->instance->id}hidden"]));
290         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
291             'name' => "block{$blockmyprofile->instance->id}hidden"]));
292         $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
293             'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
294         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
295             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
296         $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
297             'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
298     }
300     /**
301      * Test the deletion of data related to a context and a list of users.
302      */
303     public function test_delete_data_for_users() {
304         global $DB;
305         $u1 = $this->getDataGenerator()->create_user();
306         $u2 = $this->getDataGenerator()->create_user();
307         $u3 = $this->getDataGenerator()->create_user();
309         $course = $this->getDataGenerator()->create_course();
311         $manager = $this->get_block_manager(['region-a'], context_course::instance($course->id));
312         $manager->add_block('myprofile', 'region-a', 0, false);
313         $manager->load_blocks();
314         $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
316         $this->set_hidden_pref($blockmyprofile, true, $u1->id);
317         $this->set_hidden_pref($blockmyprofile, true, $u3->id);
318         $this->set_docked_pref($blockmyprofile, true, $u2->id);
319         $this->set_docked_pref($blockmyprofile, true, $u3->id);
321         $records = $DB->get_records('block_instances', ['blockname' => 'myprofile']);
322         $record = array_shift($records);
323         $blockcontext = context_block::instance($record->id);
325         $userlist = new \core_privacy\local\request\userlist($blockcontext, 'core_block');
326         provider::get_users_in_context($userlist);
327         $this->assertCount(3, $userlist->get_userids());
329         // Delete preferences for user 1 and 3 for the my profile block.
330         $userlist = new \core_privacy\local\request\approved_userlist($blockcontext, 'core_block', [$u1->id, $u3->id]);
331         provider::delete_data_for_users($userlist);
333         // Only user 2's preference is left.
334         $this->assertCount(1, $DB->get_records('user_preferences',
335                 ['name' => "docked_block_instance_{$blockcontext->instanceid}"]));
336         // All of these are gone.
337         $this->assertEmpty($DB->get_records('user_preferences',
338                 ['name' => "block{$blockcontext->instanceid}hidden"]));
339     }
341     public function test_export_data_for_user() {
342         global $DB;
343         $dg = $this->getDataGenerator();
344         $c1 = $dg->create_course();
345         $c2 = $dg->create_course();
346         $u1 = $dg->create_user();
347         $u2 = $dg->create_user();
348         $c1ctx = context_course::instance($c1->id);
349         $c2ctx = context_course::instance($c2->id);
350         $u1ctx = context_user::instance($u1->id);
351         $u2ctx = context_user::instance($u2->id);
352         $yes = transform::yesno(true);
353         $no = transform::yesno(false);
355         $manager = $this->get_block_manager(['region-a'], $c1ctx);
356         $manager->add_block('myprofile', 'region-a', 0, false);
357         $manager->add_block('login', 'region-a', 1, false);
358         $manager->add_block('mentees', 'region-a', 2, false);
359         $manager->add_block('private_files', 'region-a', 3, false);
360         $manager->load_blocks();
361         list($bmyprofile, $blogin, $bmentees, $bprivatefiles) = $manager->get_blocks_for_region('region-a');
363         // Set some user preferences.
364         $this->set_hidden_pref($blogin, true, $u1->id);
365         $this->set_docked_pref($blogin, false, $u1->id);
366         $this->set_docked_pref($blogin, true, $u2->id);
367         $this->set_hidden_pref($bprivatefiles, false, $u1->id);
368         $this->set_docked_pref($bprivatefiles, true, $u2->id);
369         $this->set_docked_pref($bmyprofile, true, $u1->id);
370         $this->set_docked_pref($bmentees, true, $u2->id);
372         // Export data.
373         provider::export_user_data(new approved_contextlist($u1, 'core_block', [$bmyprofile->context->id, $blogin->context->id,
374             $bmentees->context->id, $bprivatefiles->context->id]));
375         $prefs = writer::with_context($bmentees->context)->get_user_context_preferences('core_block');
376         $this->assertEmpty((array) $prefs);
378         $prefs = writer::with_context($blogin->context)->get_user_context_preferences('core_block');
379         $this->assertEquals($no, $prefs->block_is_docked->value);
380         $this->assertEquals($yes, $prefs->block_is_hidden->value);
382         $prefs = writer::with_context($bprivatefiles->context)->get_user_context_preferences('core_block');
383         $this->assertObjectNotHasAttribute('block_is_docked', $prefs);
384         $this->assertEquals($no, $prefs->block_is_hidden->value);
386         $prefs = writer::with_context($bmyprofile->context)->get_user_context_preferences('core_block');
387         $this->assertEquals($yes, $prefs->block_is_docked->value);
388         $this->assertObjectNotHasAttribute('block_is_hidden', $prefs);
389     }
391     /**
392      * Get the block manager.
393      *
394      * @param array $regions The regions.
395      * @param context $context The context.
396      * @param string $pagetype The page type.
397      * @param string $subpage The sub page.
398      * @return block_manager
399      */
400     protected function get_block_manager($regions, $context, $pagetype = 'page-type', $subpage = '') {
401         $page = new moodle_page();
402         $page->set_context($context);
403         $page->set_pagetype($pagetype);
404         $page->set_subpage($subpage);
405         $page->set_url(new moodle_url('/'));
407         $blockmanager = new block_manager($page);
408         $blockmanager->add_regions($regions, false);
409         $blockmanager->set_default_region($regions[0]);
411         return $blockmanager;
412     }
414     /**
415      * Set a docked preference.
416      *
417      * @param block_base $block The block.
418      * @param bool $value The value.
419      * @param int $userid The user ID.
420      */
421     protected function set_docked_pref($block, $value, $userid) {
422         set_user_preference("docked_block_instance_{$block->instance->id}", $value, $userid);
423     }
425     /**
426      * Set a hidden preference.
427      *
428      * @param block_base $block The block.
429      * @param bool $value The value.
430      * @param int $userid The user ID.
431      */
432     protected function set_hidden_pref($block, $value, $userid) {
433         set_user_preference("block{$block->instance->id}hidden", $value, $userid);
434     }