MDL-63664 tool_policy: Add support for removal of context users
[moodle.git] / admin / tool / policy / tests / privacy_provider_test.php
CommitLineData
24966a26
SA
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 * Privacy provider tests.
19 *
20 * @package tool_policy
21 * @category test
22 * @copyright 2018 Sara Arjona <sara@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26use core_privacy\local\metadata\collection;
27use tool_policy\privacy\provider;
432a90f1
MG
28use tool_policy\api;
29use tool_policy\policy_version;
30use core_privacy\local\request\approved_contextlist;
31use core_privacy\local\request\writer;
24966a26
SA
32
33defined('MOODLE_INTERNAL') || die();
34
35/**
36 * Privacy provider tests class.
37 *
38 * @copyright 2018 Sara Arjona <sara@moodle.com>
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41class tool_policy_privacy_provider_testcase extends \core_privacy\tests\provider_testcase {
42 /** @var stdClass The user object. */
43 protected $user;
44
827c8e98
SA
45 /** @var stdClass The manager user object. */
46 protected $manager;
47
f6843ac9
MH
48/** @var context_system The system context instance. */
49 protected $syscontext;
50
24966a26
SA
51 /**
52 * Setup function. Will create a user.
53 */
54 protected function setUp() {
55 $this->resetAfterTest();
56
57 $generator = $this->getDataGenerator();
58 $this->user = $generator->create_user();
24966a26 59
827c8e98
SA
60 // Create manager user.
61 $this->manager = $generator->create_user();
f6843ac9 62 $this->syscontext = context_system::instance();
827c8e98 63 $rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents');
f6843ac9
MH
64 assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $this->syscontext->id);
65 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $this->syscontext->id);
66 role_assign($rolemanagerid, $this->manager->id, $this->syscontext->id);
827c8e98 67 accesslib_clear_all_caches_for_unit_testing();
24966a26
SA
68 }
69
70 /**
71 * Test getting the context for the user ID related to this plugin.
72 */
73 public function test_get_contexts_for_userid() {
432a90f1
MG
74 global $CFG;
75
76 // When there are no policies or agreements context list is empty.
827c8e98
SA
77 $contextlist = \tool_policy\privacy\provider::get_contexts_for_userid($this->manager->id);
78 $this->assertEmpty($contextlist);
432a90f1
MG
79 $contextlist = \tool_policy\privacy\provider::get_contexts_for_userid($this->user->id);
80 $this->assertEmpty($contextlist);
81
82 // Create a policy.
827c8e98 83 $this->setUser($this->manager);
432a90f1
MG
84 $CFG->sitepolicyhandler = 'tool_policy';
85 $policy = $this->add_policy();
86 api::make_current($policy->get('id'));
87
827c8e98
SA
88 // After creating a policy, there should be manager context.
89 $contextlist = \tool_policy\privacy\provider::get_contexts_for_userid($this->manager->id);
90 $this->assertEquals(1, $contextlist->count());
91
92 // But when there are no agreements, user context list is empty.
24966a26
SA
93 $contextlist = \tool_policy\privacy\provider::get_contexts_for_userid($this->user->id);
94 $this->assertEmpty($contextlist);
432a90f1
MG
95
96 // Agree to the policy.
97 $this->setUser($this->user);
98 api::accept_policies([$policy->get('id')]);
99
100 // There should be user context.
101 $contextlist = \tool_policy\privacy\provider::get_contexts_for_userid($this->user->id);
102 $this->assertEquals(1, $contextlist->count());
103 }
104
f6843ac9
MH
105 /**
106 * Test getting the user IDs within the context related to this plugin.
107 */
108 public function test_get_users_in_context() {
109 global $CFG;
110 $component = 'tool_policy';
111
112 // System context should have nothing before a policy is added.
113 $userlist = new \core_privacy\local\request\userlist($this->syscontext, $component);
114 provider::get_users_in_context($userlist);
115 $this->assertEmpty($userlist);
116
117 // Create parent and child users.
118 $generator = $this->getDataGenerator();
119 $parentuser = $generator->create_user();
120 $childuser = $generator->create_user();
121
122 // Fetch relevant contexts.
123 $managercontext = \context_user::instance($this->manager->id);
124 $usercontext = $managercontext = \context_user::instance($this->user->id);
125 $parentcontext = $managercontext = \context_user::instance($parentuser->id);
126 $childcontext = $managercontext = \context_user::instance($childuser->id);
127
128 // Assign parent to accept on behalf of the child.
129 $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child');
130 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $this->syscontext->id);
131 role_assign($roleparentid, $parentuser->id, $childcontext->id);
132
133 // Create a policy.
134 $this->setUser($this->manager);
135 $CFG->sitepolicyhandler = 'tool_policy';
136 $policy = $this->add_policy();
137 api::make_current($policy->get('id'));
138
139 // Manager should exist in system context now they have created a policy.
140 $userlist = new \core_privacy\local\request\userlist($this->syscontext, $component);
141 provider::get_users_in_context($userlist);
142 $this->assertCount(1, $userlist);
143 $this->assertEquals([$this->manager->id], $userlist->get_userids());
144
145 // User contexts should be empty before policy acceptances.
146 $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
147 provider::get_users_in_context($userlist);
148 $this->assertEmpty($userlist);
149
150 $userlist = new \core_privacy\local\request\userlist($parentcontext, $component);
151 provider::get_users_in_context($userlist);
152 $this->assertEmpty($userlist);
153
154 $userlist = new \core_privacy\local\request\userlist($childcontext, $component);
155 provider::get_users_in_context($userlist);
156 $this->assertEmpty($userlist);
157
158 // User accepts policy, parent accepts on behalf of child only.
159 $this->setUser($this->user);
160 api::accept_policies([$policy->get('id')]);
161
162 $this->setUser($parentuser);
163 api::accept_policies([$policy->get('id')], $childuser->id);
164
165 // Ensure user is fetched within its user context.
166 $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
167 provider::get_users_in_context($userlist);
168 $this->assertCount(1, $userlist);
169 $this->assertEquals([$this->user->id], $userlist->get_userids());
170
171 // Ensure parent and child are both found within child's user context.
172 $userlist = new \core_privacy\local\request\userlist($childcontext, $component);
173 provider::get_users_in_context($userlist);
174 $this->assertCount(2, $userlist);
175 $expected = [$parentuser->id, $childuser->id];
176 $actual = $userlist->get_userids();
177 sort($expected);
178 sort($actual);
179 $this->assertEquals($expected, $actual);
180
181 // Parent has not accepted for itself, so should not be found within its user context.
182 $userlist = new \core_privacy\local\request\userlist($parentcontext, $component);
183 provider::get_users_in_context($userlist);
184 $this->assertCount(0, $userlist);
185 }
186
f63745ea 187 public function test_export_agreements() {
827c8e98 188 global $CFG;
432a90f1 189
f63745ea
AN
190 $otheruser = $this->getDataGenerator()->create_user();
191 $otherusercontext = \context_user::instance($otheruser->id);
192
827c8e98
SA
193 // Create policies and agree to them as manager.
194 $this->setUser($this->manager);
195 $managercontext = \context_user::instance($this->manager->id);
196 $systemcontext = \context_system::instance();
197 $agreementsubcontext = [
198 get_string('privacyandpolicies', 'admin'),
199 get_string('useracceptances', 'tool_policy')
200 ];
201 $versionsubcontext = [
202 get_string('policydocuments', 'tool_policy')
203 ];
432a90f1
MG
204 $CFG->sitepolicyhandler = 'tool_policy';
205 $policy1 = $this->add_policy();
206 api::make_current($policy1->get('id'));
207 $policy2 = $this->add_policy();
208 api::make_current($policy2->get('id'));
209 api::accept_policies([$policy1->get('id'), $policy2->get('id')]);
210
211 // Agree to the policies for oneself.
212 $this->setUser($this->user);
fd7174d0 213 $usercontext = \context_user::instance($this->user->id);
432a90f1
MG
214 api::accept_policies([$policy1->get('id'), $policy2->get('id')]);
215
216 // Request export for this user.
217 $contextlist = provider::get_contexts_for_userid($this->user->id);
f63745ea 218 $this->assertCount(1, $contextlist);
432a90f1
MG
219 $this->assertEquals([$usercontext->id], $contextlist->get_contextids());
220
221 $approvedcontextlist = new approved_contextlist($this->user, 'tool_policy', [$usercontext->id]);
222 provider::export_user_data($approvedcontextlist);
223
827c8e98
SA
224 // User can not see manager's agreements but can see his own.
225 $writer = writer::with_context($managercontext);
f63745ea 226 $this->assertFalse($writer->has_any_data());
432a90f1
MG
227
228 $writer = writer::with_context($usercontext);
f63745ea
AN
229 $this->assertTrue($writer->has_any_data());
230
231 // Test policy 1.
232 $subcontext = array_merge($agreementsubcontext, [get_string('policynamedversion', 'tool_policy', $policy1->to_record())]);
233 $datauser = $writer->get_data($subcontext);
234 $this->assertEquals($policy1->get('name'), $datauser->name);
235 $this->assertEquals($this->user->id, $datauser->agreedby);
236 $this->assertEquals(strip_tags($policy1->get('summary')), strip_tags($datauser->summary));
237 $this->assertEquals(strip_tags($policy1->get('content')), strip_tags($datauser->content));
238
239 // Test policy 2.
240 $subcontext = array_merge($agreementsubcontext, [get_string('policynamedversion', 'tool_policy', $policy2->to_record())]);
241 $datauser = $writer->get_data($subcontext);
242 $this->assertEquals($policy2->get('name'), $datauser->name);
243 $this->assertEquals($this->user->id, $datauser->agreedby);
244 $this->assertEquals(strip_tags($policy2->get('summary')), strip_tags($datauser->summary));
245 $this->assertEquals(strip_tags($policy2->get('content')), strip_tags($datauser->content));
432a90f1
MG
246 }
247
f63745ea 248 public function test_export_agreements_for_other() {
827c8e98 249 global $CFG;
432a90f1 250
827c8e98
SA
251 $managercontext = \context_user::instance($this->manager->id);
252 $systemcontext = \context_system::instance();
f63745ea
AN
253 $usercontext = \context_user::instance($this->user->id);
254
255 // Create policies and agree to them as manager.
256 $this->setUser($this->manager);
827c8e98
SA
257 $agreementsubcontext = [
258 get_string('privacyandpolicies', 'admin'),
259 get_string('useracceptances', 'tool_policy')
260 ];
261 $versionsubcontext = [
262 get_string('policydocuments', 'tool_policy')
263 ];
432a90f1
MG
264 $CFG->sitepolicyhandler = 'tool_policy';
265 $policy1 = $this->add_policy();
266 api::make_current($policy1->get('id'));
267 $policy2 = $this->add_policy();
268 api::make_current($policy2->get('id'));
432a90f1 269 api::accept_policies([$policy1->get('id'), $policy2->get('id')]);
432a90f1 270
f63745ea
AN
271 // Agree to the other user's policies.
272 api::accept_policies([$policy1->get('id'), $policy2->get('id')], $this->user->id, 'My note');
432a90f1 273
f63745ea
AN
274 // Request export for the manager.
275 $contextlist = provider::get_contexts_for_userid($this->manager->id);
276 $this->assertCount(3, $contextlist);
5e84f521
SA
277 $this->assertEquals(
278 [$managercontext->id, $usercontext->id, $systemcontext->id],
279 $contextlist->get_contextids(),
280 '',
281 0.0,
282 1,
283 true
284 );
432a90f1
MG
285
286 $approvedcontextlist = new approved_contextlist($this->user, 'tool_policy', [$usercontext->id]);
287 provider::export_user_data($approvedcontextlist);
288
f63745ea
AN
289 // The user context has data.
290 $writer = writer::with_context($usercontext);
291 $this->assertTrue($writer->has_any_data());
432a90f1 292
f63745ea 293 // Test policy 1.
432a90f1 294 $writer = writer::with_context($usercontext);
f63745ea
AN
295 $subcontext = array_merge($agreementsubcontext, [get_string('policynamedversion', 'tool_policy', $policy1->to_record())]);
296 $datauser = $writer->get_data($subcontext);
297 $this->assertEquals($policy1->get('name'), $datauser->name);
298 $this->assertEquals($this->manager->id, $datauser->agreedby);
299 $this->assertEquals(strip_tags($policy1->get('summary')), strip_tags($datauser->summary));
300 $this->assertEquals(strip_tags($policy1->get('content')), strip_tags($datauser->content));
301
302 // Test policy 2.
303 $subcontext = array_merge($agreementsubcontext, [get_string('policynamedversion', 'tool_policy', $policy2->to_record())]);
304 $datauser = $writer->get_data($subcontext);
305 $this->assertEquals($policy2->get('name'), $datauser->name);
306 $this->assertEquals($this->manager->id, $datauser->agreedby);
307 $this->assertEquals(strip_tags($policy2->get('summary')), strip_tags($datauser->summary));
308 $this->assertEquals(strip_tags($policy2->get('content')), strip_tags($datauser->content));
309 }
432a90f1 310
f63745ea
AN
311 public function test_export_created_policies() {
312 global $CFG;
827c8e98 313
f63745ea
AN
314 // Create policies and agree to them as manager.
315 $this->setUser($this->manager);
316 $managercontext = \context_user::instance($this->manager->id);
317 $systemcontext = \context_system::instance();
318 $agreementsubcontext = [
319 get_string('privacyandpolicies', 'admin'),
320 get_string('useracceptances', 'tool_policy')
321 ];
322 $versionsubcontext = [
323 get_string('policydocuments', 'tool_policy')
324 ];
325 $CFG->sitepolicyhandler = 'tool_policy';
326 $policy1 = $this->add_policy();
327 api::make_current($policy1->get('id'));
328 $policy2 = $this->add_policy();
329 api::make_current($policy2->get('id'));
330 api::accept_policies([$policy1->get('id'), $policy2->get('id')]);
331
332 // Agree to the policies for oneself.
827c8e98 333 $contextlist = provider::get_contexts_for_userid($this->manager->id);
f63745ea
AN
334 $this->assertCount(2, $contextlist);
335 $this->assertEquals([$managercontext->id, $systemcontext->id], $contextlist->get_contextids(), '', 0.0, 1, true);
432a90f1 336
827c8e98 337 $approvedcontextlist = new approved_contextlist($this->manager, 'tool_policy', $contextlist->get_contextids());
432a90f1
MG
338 provider::export_user_data($approvedcontextlist);
339
f63745ea 340 // User has agreed to policies.
827c8e98 341 $writer = writer::with_context($managercontext);
f63745ea
AN
342 $this->assertTrue($writer->has_any_data());
343
344 // Test policy 1.
345 $subcontext = array_merge($agreementsubcontext, [get_string('policynamedversion', 'tool_policy', $policy1->to_record())]);
346 $datauser = $writer->get_data($subcontext);
347 $this->assertEquals($policy1->get('name'), $datauser->name);
348 $this->assertEquals($this->manager->id, $datauser->agreedby);
349 $this->assertEquals(strip_tags($policy1->get('summary')), strip_tags($datauser->summary));
350 $this->assertEquals(strip_tags($policy1->get('content')), strip_tags($datauser->content));
351
352 // Test policy 2.
353 $subcontext = array_merge($agreementsubcontext, [get_string('policynamedversion', 'tool_policy', $policy2->to_record())]);
354 $datauser = $writer->get_data($subcontext);
355 $this->assertEquals($policy2->get('name'), $datauser->name);
356 $this->assertEquals($this->manager->id, $datauser->agreedby);
357 $this->assertEquals(strip_tags($policy2->get('summary')), strip_tags($datauser->summary));
358 $this->assertEquals(strip_tags($policy2->get('content')), strip_tags($datauser->content));
827c8e98 359
f63745ea 360 // User can see policy documents.
827c8e98 361 $writer = writer::with_context($systemcontext);
f63745ea
AN
362 $this->assertTrue($writer->has_any_data());
363
364 $subcontext = array_merge($versionsubcontext, [get_string('policynamedversion', 'tool_policy', $policy1->to_record())]);
365 $dataversion = $writer->get_data($subcontext);
366 $this->assertEquals($policy1->get('name'), $dataversion->name);
367 $this->assertEquals(get_string('yes'), $dataversion->createdbyme);
368
369 $subcontext = array_merge($versionsubcontext, [get_string('policynamedversion', 'tool_policy', $policy2->to_record())]);
370 $dataversion = $writer->get_data($subcontext);
371 $this->assertEquals($policy2->get('name'), $dataversion->name);
372 $this->assertEquals(get_string('yes'), $dataversion->createdbyme);
432a90f1
MG
373 }
374
375 /**
376 * Helper method that creates a new policy for testing
377 *
378 * @param array $params
379 * @return policy_version
380 */
381 protected function add_policy($params = []) {
382 static $counter = 0;
383 $counter++;
384
385 $defaults = [
386 'name' => 'Policy '.$counter,
387 'summary_editor' => ['text' => "P$counter summary", 'format' => FORMAT_HTML, 'itemid' => 0],
388 'content_editor' => ['text' => "P$counter content", 'format' => FORMAT_HTML, 'itemid' => 0],
389 ];
390
391 $params = (array)$params + $defaults;
392 $formdata = \tool_policy\api::form_policydoc_data(new policy_version(0));
393 foreach ($params as $key => $value) {
394 $formdata->$key = $value;
395 }
396 return api::form_policydoc_add($formdata);
24966a26
SA
397 }
398}