MDL-68567 badges: add/remove site backpacks
[moodle.git] / badges / tests / privacy_test.php
blob8067b4ef1a51eec31472c4e93f981cf82a42f5ef
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.
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.
20 * @package core_badges
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
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_badges\privacy\provider;
35 use core_privacy\local\request\approved_userlist;
36 use core_badges\helper;
38 require_once($CFG->libdir . '/badgeslib.php');
40 /**
41 * Data provider testcase class.
43 * @package core_badges
44 * @category test
45 * @copyright 2018 Frédéric Massart
46 * @author Frédéric Massart <fred@branchup.tech>
47 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
49 class core_badges_privacy_testcase extends provider_testcase {
51 public function setUp() {
52 $this->resetAfterTest();
55 public function test_get_contexts_for_userid_for_badge_editing() {
56 $dg = $this->getDataGenerator();
57 $u1 = $dg->create_user();
58 $u2 = $dg->create_user();
59 $u3 = $dg->create_user();
60 $u4 = $dg->create_user();
61 $u5 = $dg->create_user();
62 $c1 = $dg->create_course();
63 $c2 = $dg->create_course();
64 $sysctx = context_system::instance();
65 $c1ctx = context_course::instance($c1->id);
66 $c2ctx = context_course::instance($c2->id);
68 // Assert that we find contexts where we created/modified a badge.
69 $this->create_badge(['usercreated' => $u1->id, 'usermodified' => $u5->id]);
70 $this->create_badge(['usercreated' => $u2->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
71 $this->create_badge(['usermodified' => $u3->id]);
72 $this->create_badge(['usermodified' => $u4->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $c2->id,
73 'usercreated' => $u5->id]);
75 $contexts = provider::get_contexts_for_userid($u1->id)->get_contextids();
76 $this->assertCount(1, $contexts);
77 $this->assertEquals($sysctx->id, $contexts[0]);
79 $contexts = provider::get_contexts_for_userid($u2->id)->get_contextids();
80 $this->assertCount(1, $contexts);
81 $this->assertEquals($c1ctx->id, $contexts[0]);
83 $contexts = provider::get_contexts_for_userid($u3->id)->get_contextids();
84 $this->assertCount(1, $contexts);
85 $this->assertEquals($sysctx->id, $contexts[0]);
87 $contexts = provider::get_contexts_for_userid($u4->id)->get_contextids();
88 $this->assertCount(1, $contexts);
89 $this->assertEquals($c2ctx->id, $contexts[0]);
91 $contexts = provider::get_contexts_for_userid($u5->id)->get_contextids();
92 $this->assertCount(2, $contexts);
93 $this->assertTrue(in_array($sysctx->id, $contexts));
94 $this->assertTrue(in_array($c2ctx->id, $contexts));
97 public function test_get_contexts_for_userid_for_manual_award() {
98 global $DB;
100 $dg = $this->getDataGenerator();
101 $u1 = $dg->create_user();
102 $u2 = $dg->create_user();
103 $u3 = $dg->create_user();
104 $u4 = $dg->create_user();
105 $c1 = $dg->create_course();
106 $sysctx = context_system::instance();
107 $c1ctx = context_course::instance($c1->id);
108 $u1ctx = context_user::instance($u1->id);
109 $u2ctx = context_user::instance($u2->id);
110 $u3ctx = context_user::instance($u3->id);
111 $u4ctx = context_user::instance($u4->id);
112 $b1 = $this->create_badge();
113 $b2 = $this->create_badge(['type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
115 $this->create_manual_award(['recipientid' => $u4->id, 'issuerid' => $u1->id, 'badgeid' => $b1->id]);
116 $this->create_manual_award(['recipientid' => $u3->id, 'issuerid' => $u2->id, 'badgeid' => $b1->id]);
117 $this->create_manual_award(['recipientid' => $u3->id, 'issuerid' => $u2->id, 'badgeid' => $b2->id]);
119 $contexts = provider::get_contexts_for_userid($u1->id)->get_contextids();
120 $this->assertCount(1, $contexts);
121 $this->assertEquals($u4ctx->id, $contexts[0]);
123 $contexts = provider::get_contexts_for_userid($u2->id)->get_contextids();
124 $this->assertCount(1, $contexts);
125 $this->assertEquals($u3ctx->id, $contexts[0]);
128 public function test_get_contexts_for_userid_for_my_stuff() {
129 global $DB;
131 $dg = $this->getDataGenerator();
132 $u1 = $dg->create_user();
133 $u2 = $dg->create_user();
134 $u3 = $dg->create_user();
135 $u4 = $dg->create_user();
136 $c1 = $dg->create_course();
137 $sysctx = context_system::instance();
138 $c1ctx = context_course::instance($c1->id);
139 $u1ctx = context_user::instance($u1->id);
140 $u2ctx = context_user::instance($u2->id);
141 $u3ctx = context_user::instance($u3->id);
142 $u4ctx = context_user::instance($u4->id);
143 $b1 = $this->create_badge();
144 $b2 = $this->create_badge(['type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
146 helper::create_fake_backpack(['userid' => $u1->id]);
147 $this->create_manual_award(['recipientid' => $u2->id, 'badgeid' => $b1->id]);
148 $this->create_issued(['badgeid' => $b2->id, 'userid' => $u3->id]);
150 $crit = $this->create_criteria_manual($b1->id);
151 $crit->mark_complete($u4->id);
153 $contexts = provider::get_contexts_for_userid($u1->id)->get_contextids();
154 $this->assertCount(1, $contexts);
155 $this->assertEquals($u1ctx->id, $contexts[0]);
157 $contexts = provider::get_contexts_for_userid($u2->id)->get_contextids();
158 $this->assertCount(1, $contexts);
159 $this->assertEquals($u2ctx->id, $contexts[0]);
161 $contexts = provider::get_contexts_for_userid($u3->id)->get_contextids();
162 $this->assertCount(1, $contexts);
163 $this->assertEquals($u3ctx->id, $contexts[0]);
165 $contexts = provider::get_contexts_for_userid($u4->id)->get_contextids();
166 $this->assertCount(1, $contexts);
167 $this->assertEquals($u4ctx->id, $contexts[0]);
170 public function test_delete_data_for_user() {
171 global $DB;
173 $dg = $this->getDataGenerator();
174 $u1 = $dg->create_user();
175 $u2 = $dg->create_user();
176 $c1 = $dg->create_course();
177 $sysctx = context_system::instance();
178 $c1ctx = context_course::instance($c1->id);
179 $u1ctx = context_user::instance($u1->id);
180 $u2ctx = context_user::instance($u2->id);
182 $b1 = $this->create_badge(['usercreated' => $u1->id, 'usermodified' => $u2->id]);
183 $b2 = $this->create_badge(['usercreated' => $u2->id, 'usermodified' => $u1->id,
184 'type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
186 helper::create_fake_backpack(['userid' => $u1->id]);
187 helper::create_fake_backpack(['userid' => $u2->id]);
188 $this->create_manual_award(['recipientid' => $u1->id, 'badgeid' => $b1->id]);
189 $this->create_manual_award(['recipientid' => $u2->id, 'badgeid' => $b1->id, 'issuerid' => $u1->id]);
190 $this->create_issued(['badgeid' => $b2->id, 'userid' => $u1->id]);
191 $this->create_issued(['badgeid' => $b2->id, 'userid' => $u2->id]);
193 $crit = $this->create_criteria_manual($b1->id);
194 $crit->mark_complete($u2->id);
195 $crit = $this->create_criteria_manual($b2->id);
196 $crit->mark_complete($u1->id);
198 $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
199 $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
200 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
201 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
202 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
203 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
204 $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
205 $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
206 $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u1->id]));
207 $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
208 $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
209 $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
211 provider::delete_data_for_user(new approved_contextlist($u1, 'core_badges', [$sysctx->id, $c1ctx->id,
212 $u1ctx->id, $u2ctx->id]));
214 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
215 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
216 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
217 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
218 $this->assertFalse($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
219 $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
220 $this->assertFalse($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
221 $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
222 $this->assertFalse($DB->record_exists('badge_issued', ['userid' => $u1->id]));
223 $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
224 $this->assertFalse($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
225 $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
228 public function test_delete_data_for_all_users_in_context() {
229 global $DB;
231 $dg = $this->getDataGenerator();
232 $u1 = $dg->create_user();
233 $u2 = $dg->create_user();
234 $c1 = $dg->create_course();
235 $sysctx = context_system::instance();
236 $c1ctx = context_course::instance($c1->id);
237 $u1ctx = context_user::instance($u1->id);
238 $u2ctx = context_user::instance($u2->id);
240 $b1 = $this->create_badge(['usercreated' => $u1->id, 'usermodified' => $u2->id]);
241 $b2 = $this->create_badge(['usercreated' => $u2->id, 'usermodified' => $u1->id,
242 'type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
244 helper::create_fake_backpack(['userid' => $u1->id]);
245 helper::create_fake_backpack(['userid' => $u2->id]);
246 $this->create_manual_award(['recipientid' => $u1->id, 'badgeid' => $b1->id]);
247 $this->create_manual_award(['recipientid' => $u2->id, 'badgeid' => $b1->id, 'issuerid' => $u1->id]);
248 $this->create_issued(['badgeid' => $b2->id, 'userid' => $u1->id]);
249 $this->create_issued(['badgeid' => $b2->id, 'userid' => $u2->id]);
251 $crit = $this->create_criteria_manual($b1->id);
252 $crit->mark_complete($u2->id);
253 $crit = $this->create_criteria_manual($b2->id);
254 $crit->mark_complete($u1->id);
256 $assertnochange = function() use ($DB, $u1, $u2) {
257 $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
258 $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
259 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
260 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
261 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
262 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
263 $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
264 $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
265 $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u1->id]));
266 $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
267 $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
268 $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
270 $assertnochange();
272 provider::delete_data_for_all_users_in_context($sysctx);
273 $assertnochange();
275 provider::delete_data_for_all_users_in_context($c1ctx);
276 $assertnochange();
278 provider::delete_data_for_all_users_in_context($u1ctx);
279 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
280 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
281 $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
282 $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
283 $this->assertFalse($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
284 $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
285 $this->assertFalse($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
286 $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
287 $this->assertFalse($DB->record_exists('badge_issued', ['userid' => $u1->id]));
288 $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
289 $this->assertFalse($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
290 $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
293 public function test_export_data_for_user() {
294 global $DB;
296 $yes = transform::yesno(true);
297 $no = transform::yesno(false);
299 $dg = $this->getDataGenerator();
300 $u1 = $dg->create_user();
301 $u2 = $dg->create_user();
302 $u3 = $dg->create_user();
303 $c1 = $dg->create_course();
304 $sysctx = context_system::instance();
305 $c1ctx = context_course::instance($c1->id);
306 $u1ctx = context_user::instance($u1->id);
307 $u2ctx = context_user::instance($u2->id);
309 $b1 = $this->create_badge(['usercreated' => $u3->id]);
310 $this->endorse_badge(['badgeid' => $b1->id]);
311 $this->align_badge(['badgeid' => $b1->id], ' (1)');
312 $this->align_badge(['badgeid' => $b1->id], ' (2)');
313 $b2 = $this->create_badge(['type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id, 'usermodified' => $u3->id]);
314 $this->relate_badge($b1->id, $b2->id);
315 $b3 = $this->create_badge();
316 $b3crit = $this->create_criteria_manual($b3->id);
317 $b4 = $this->create_badge();
319 // Create things for user 2, to check it's not exported it.
320 $this->create_issued(['badgeid' => $b4->id, 'userid' => $u2->id]);
321 helper::create_fake_backpack(['userid' => $u2->id, 'email' => $u2->email]);
322 $this->create_manual_award(['badgeid' => $b1->id, 'recipientid' => $u2->id, 'issuerid' => $u3->id]);
324 // Create a set of stuff for u1.
325 $this->create_issued(['badgeid' => $b1->id, 'userid' => $u1->id, 'uniquehash' => 'yoohoo']);
326 $this->create_manual_award(['badgeid' => $b2->id, 'recipientid' => $u1->id, 'issuerid' => $u3->id]);
327 $b3crit->mark_complete($u1->id);
328 helper::create_fake_backpack(['userid' => $u1->id, 'email' => $u1->email]);
330 // Check u1.
331 writer::reset();
332 provider::export_user_data(new approved_contextlist($u1, 'core_badges', [$u1ctx->id, $u2ctx->id,
333 $sysctx->id, $c1ctx->id]));
334 $this->assertFalse(writer::with_context($u2ctx)->has_any_data());
335 $this->assertFalse(writer::with_context($sysctx)->has_any_data());
336 $this->assertFalse(writer::with_context($c1ctx)->has_any_data());
338 $path = [get_string('badges', 'core_badges'), "{$b1->name} ({$b1->id})"];
339 $data = writer::with_context($u1ctx)->get_data($path);
340 $this->assertEquals($b1->name, $data->name);
341 $this->assertEquals($b1->version, $data->version);
342 $this->assertEquals($b1->language, $data->language);
343 $this->assertEquals($b1->imageauthorname, $data->imageauthorname);
344 $this->assertEquals($b1->imageauthoremail, $data->imageauthoremail);
345 $this->assertEquals($b1->imageauthorurl, $data->imageauthorurl);
346 $this->assertEquals($b1->imagecaption, $data->imagecaption);
347 $this->assertNotEmpty($data->issued);
348 $this->assertEmpty($data->manual_award);
349 $this->assertEmpty($data->criteria_met);
350 $this->assertFalse(isset($data->course));
351 $this->assertEquals('yoohoo', $data->issued['unique_hash']);
352 $this->assertNull($data->issued['expires_on']);
354 $this->assertNotEmpty($data->endorsement);
355 $this->assertNotEmpty($data->endorsement['issuername']);
356 $this->assertNotEmpty($data->endorsement['issuerurl']);
357 $this->assertNotEmpty($data->endorsement['issueremail']);
358 $this->assertNotEmpty($data->endorsement['claimid']);
359 $this->assertNotEmpty($data->endorsement['claimcomment']);
360 $this->assertNotEmpty($data->endorsement['dateissued']);
362 $this->assertNotEmpty($data->related_badge);
363 $this->assertNotEmpty($data->related_badge[0]);
364 $this->assertEquals($data->related_badge[0]['badgeid'], $b2->id);
365 $this->assertEquals($data->related_badge[0]['badgename'], $b2->name);
367 $this->assertNotEmpty($data->alignment);
368 $this->assertNotEmpty($data->alignment[0]);
369 $this->assertNotEmpty($data->alignment[0]['targetname']);
370 $this->assertNotEmpty($data->alignment[0]['targeturl']);
371 $this->assertNotEmpty($data->alignment[0]['targetdescription']);
372 $this->assertNotEmpty($data->alignment[0]['targetframework']);
373 $this->assertNotEmpty($data->alignment[0]['targetcode']);
374 $this->assertNotEmpty($data->alignment[1]);
375 $this->assertNotEmpty($data->alignment[1]['targetname']);
376 $this->assertNotEmpty($data->alignment[1]['targeturl']);
377 $this->assertNotEmpty($data->alignment[1]['targetdescription']);
378 $this->assertNotEmpty($data->alignment[1]['targetframework']);
379 $this->assertNotEmpty($data->alignment[1]['targetcode']);
381 $path = [get_string('badges', 'core_badges'), "{$b2->name} ({$b2->id})"];
382 $data = writer::with_context($u1ctx)->get_data($path);
383 $this->assertEquals($b2->name, $data->name);
384 $this->assertEmpty($data->issued);
385 $this->assertNotEmpty($data->manual_award);
386 $this->assertEmpty($data->criteria_met);
387 $this->assertEquals($c1->fullname, $data->course);
388 $this->assertEquals($u3->id, $data->manual_award['issuer']);
390 $path = [get_string('badges', 'core_badges'), "{$b3->name} ({$b3->id})"];
391 $data = writer::with_context($u1ctx)->get_data($path);
392 $this->assertEquals($b3->name, $data->name);
393 $this->assertEmpty($data->issued);
394 $this->assertEmpty($data->manual_award);
395 $this->assertNotEmpty($data->criteria_met);
396 $this->assertNotFalse(strpos($data->criteria_met[0], get_string('criteria_descr_2', 'core_badges', 'ALL')));
398 $path = [get_string('badges', 'core_badges')];
399 $data = writer::with_context($u1ctx)->get_related_data($path, 'backpacks');
400 $this->assertCount(1, $data->backpacks);
401 $this->assertEquals($u1->email, $data->backpacks[0]['email']);
403 // Confirm we do not have u2.
404 $path = [get_string('badges', 'core_badges'), "{$b4->name} ({$b4->id})"];
405 $data = writer::with_context($u1ctx)->get_data($path);
406 $this->assertEmpty($data);
407 $data = writer::with_context($u2ctx)->get_data($path);
408 $this->assertEmpty($data);
410 // Export for u3.
411 writer::reset();
412 $path = [get_string('badges', 'core_badges')];
413 provider::export_user_data(new approved_contextlist($u3, 'core_badges', [$u1ctx->id, $u2ctx->id,
414 $sysctx->id, $c1ctx->id]));
416 $data = writer::with_context($u2ctx)->get_related_data($path, 'manual_awards');
417 $this->assertCount(1, $data->badges);
418 $this->assertEquals($b1->name, $data->badges[0]['name']);
419 $this->assertEquals($yes, $data->badges[0]['issued_by_you']);
420 $this->assertEquals('Manager', $data->badges[0]['issuer_role']);
422 $data = writer::with_context($sysctx)->get_data($path);
423 $this->assertCount(1, $data->badges);
424 $this->assertEquals($b1->name, $data->badges[0]['name']);
425 $this->assertEquals($yes, $data->badges[0]['created_by_you']);
426 $this->assertEquals($no, $data->badges[0]['modified_by_you']);
428 $data = writer::with_context($c1ctx)->get_data($path);
429 $this->assertCount(1, $data->badges);
430 $this->assertEquals($b2->name, $data->badges[0]['name']);
431 $this->assertEquals($no, $data->badges[0]['created_by_you']);
432 $this->assertEquals($yes, $data->badges[0]['modified_by_you']);
434 $data = writer::with_context($u1ctx)->get_related_data($path, 'manual_awards');
435 $this->assertCount(1, $data->badges);
436 $this->assertEquals($b3->name, $data->badges[0]['name']);
437 $this->assertEquals($yes, $data->badges[0]['issued_by_you']);
438 $this->assertEquals('Manager', $data->badges[0]['issuer_role']);
442 * Test that only users within a user, system and course context are fetched.
444 public function test_get_users_in_context() {
445 $component = 'core_badges';
447 // Create course1.
448 $course1 = $this->getDataGenerator()->create_course();
449 $coursecontext1 = context_course::instance($course1->id);
450 // Create course2.
451 $course2 = $this->getDataGenerator()->create_course();
452 $coursecontext2 = context_course::instance($course2->id);
453 // Create user1.
454 $user1 = $this->getDataGenerator()->create_user();
455 $usercontext1 = context_user::instance($user1->id);
456 // Create user2.
457 $user2 = $this->getDataGenerator()->create_user();
458 $usercontext2 = context_user::instance($user2->id);
459 // Create user3.
460 $user3 = $this->getDataGenerator()->create_user();
461 $usercontext3 = context_user::instance($user3->id);
463 // The list of users in usercontext1 should not return anything yet (related data still haven't been created).
464 $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
465 provider::get_users_in_context($userlist1);
466 $this->assertCount(0, $userlist1);
467 // The list of users in coursecontext1 should not return anything yet (related data still haven't been created).
468 $userlist2 = new \core_privacy\local\request\userlist($coursecontext1, $component);
469 provider::get_users_in_context($userlist2);
470 $this->assertCount(0, $userlist2);
471 // The list of users in systemcontext should not return anything yet (related data still haven't been created).
472 $systemcontext = context_system::instance();
473 $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
474 provider::get_users_in_context($userlist3);
475 $this->assertCount(0, $userlist3);
477 // Assert that we find contexts where we created/modified a badge.
478 $this->create_badge(['usercreated' => $user1->id, 'usermodified' => $user2->id]);
479 $badge1 = $this->create_badge(['usercreated' => $user2->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $course1->id]);
480 $badge2 = $this->create_badge(['usercreated' => $user3->id, 'usermodified' => $user1->id]);
482 $this->create_manual_award(['recipientid' => $user2->id, 'issuerid' => $user1->id, 'badgeid' => $badge1->id]);
483 $this->create_manual_award(['recipientid' => $user3->id, 'issuerid' => $user2->id, 'badgeid' => $badge1->id]);
484 $this->create_manual_award(['recipientid' => $user1->id, 'issuerid' => $user2->id, 'badgeid' => $badge2->id]);
486 helper::create_fake_backpack(['userid' => $user2->id]);
487 $this->create_issued(['badgeid' => $badge2->id, 'userid' => $user3->id]);
489 $crit = $this->create_criteria_manual($badge1->id);
490 $crit->mark_complete($user3->id);
492 // The list of users for user context should return user1 and user2.
493 provider::get_users_in_context($userlist1);
494 $this->assertCount(2, $userlist1);
495 $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
496 $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
498 // The list of users for course context should return user2.
499 provider::get_users_in_context($userlist2);
500 $this->assertCount(1, $userlist2);
501 $this->assertTrue(in_array($user2->id, $userlist2->get_userids()));
503 // The list of users for system context should return user1, user2 and user3.
504 provider::get_users_in_context($userlist3);
505 $this->assertCount(3, $userlist3);
506 $this->assertTrue(in_array($user1->id, $userlist3->get_userids()));
507 $this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
508 $this->assertTrue(in_array($user3->id, $userlist3->get_userids()));
512 * Test that data for users in approved userlist is deleted.
514 public function test_delete_data_for_users() {
515 $component = 'core_badges';
517 // Create course1.
518 $course1 = $this->getDataGenerator()->create_course();
519 $coursecontext1 = context_course::instance($course1->id);
520 // Create course2.
521 $course2 = $this->getDataGenerator()->create_course();
522 $coursecontext2 = context_course::instance($course2->id);
523 // Create user1.
524 $user1 = $this->getDataGenerator()->create_user();
525 $usercontext1 = context_user::instance($user1->id);
526 // Create user2.
527 $user2 = $this->getDataGenerator()->create_user();
528 $usercontext2 = context_user::instance($user2->id);
529 // Create user3.
530 $user3 = $this->getDataGenerator()->create_user();
531 $usercontext3 = context_user::instance($user3->id);
533 $this->create_badge(['usercreated' => $user1->id, 'usermodified' => $user2->id]);
534 $badge1 = $this->create_badge(['usercreated' => $user2->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $course1->id]);
535 $badge2 = $this->create_badge(['usercreated' => $user3->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $course2->id,
536 'usermodified' => $user1->id]);
538 $this->create_manual_award(['recipientid' => $user2->id, 'issuerid' => $user1->id, 'badgeid' => $badge1->id]);
539 $this->create_manual_award(['recipientid' => $user3->id, 'issuerid' => $user2->id, 'badgeid' => $badge1->id]);
540 $this->create_manual_award(['recipientid' => $user1->id, 'issuerid' => $user2->id, 'badgeid' => $badge2->id]);
542 helper::create_fake_backpack(['userid' => $user2->id]);
543 $this->create_issued(['badgeid' => $badge2->id, 'userid' => $user3->id]);
545 $crit = $this->create_criteria_manual($badge1->id);
546 $crit->mark_complete($user3->id);
548 // The list of users for usercontext2 context should return users.
549 $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
550 provider::get_users_in_context($userlist1);
551 $this->assertCount(2, $userlist1);
552 $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
553 $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
555 // The list of users for coursecontext2 context should return users.
556 $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
557 provider::get_users_in_context($userlist2);
558 $this->assertCount(2, $userlist2);
559 $this->assertTrue(in_array($user1->id, $userlist2->get_userids()));
560 $this->assertTrue(in_array($user3->id, $userlist2->get_userids()));
562 // The list of users for system context should return users.
563 $systemcontext = context_system::instance();
564 $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
565 provider::get_users_in_context($userlist3);
566 $this->assertCount(2, $userlist3);
567 $this->assertTrue(in_array($user1->id, $userlist3->get_userids()));
568 $this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
570 // Delete the data for user1 in usercontext2.
571 $approvedlist = new approved_userlist($usercontext2, $component, [$user1->id]);
572 // Delete using delete_data_for_user. No data for users in usercontext2 should be removed.
573 provider::delete_data_for_users($approvedlist);
574 // The list of users for usercontext2 context should still return user1, user2.
575 $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
576 provider::get_users_in_context($userlist1);
577 $this->assertCount(2, $userlist1);
578 $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
579 $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
581 // Delete the data for user2 in usercontext2.
582 $approvedlist = new approved_userlist($usercontext2, $component, [$user2->id]);
583 // Delete using delete_data_for_user. The user data in usercontext2 should be removed.
584 provider::delete_data_for_users($approvedlist);
585 // The list of users for usercontext2 context should not return any users.
586 $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
587 provider::get_users_in_context($userlist1);
588 $this->assertCount(0, $userlist1);
590 // The list of users for coursecontext2 context should return the previous users.
591 $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
592 provider::get_users_in_context($userlist2);
593 $this->assertCount(2, $userlist2);
595 // The list of users for system context should return the previous users.
596 $systemcontext = context_system::instance();
597 $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
598 provider::get_users_in_context($userlist3);
599 $this->assertCount(2, $userlist3);
601 // Make sure data is only deleted in the user context, nothing in course or system.
602 // Convert $userlist2 into an approved_contextlist.
603 $approvedlist = new approved_userlist($coursecontext2, $component, $userlist2->get_userids());
604 provider::delete_data_for_users($approvedlist);
606 // The list of users for coursecontext2 context should still return the user data.
607 $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
608 provider::get_users_in_context($userlist2);
609 $this->assertCount(2, $userlist2);
613 * Create a badge.
615 * @param array $params Parameters.
616 * @return object
618 protected function create_badge(array $params = []) {
619 global $DB, $USER;
620 $record = (object) array_merge([
621 'name' => "Test badge with 'apostrophe' and other friends (<>&@#)",
622 'description' => "Testing badges",
623 'timecreated' => time(),
624 'timemodified' => time(),
625 'usercreated' => $USER->id,
626 'usermodified' => $USER->id,
627 'issuername' => "Test issuer",
628 'issuerurl' => "http://issuer-url.domain.co.nz",
629 'issuercontact' => "issuer@example.com",
630 'expiredate' => null,
631 'expireperiod' => null,
632 'type' => BADGE_TYPE_SITE,
633 'courseid' => null,
634 'messagesubject' => "Test message subject",
635 'message' => "Test message body",
636 'attachment' => 1,
637 'notification' => 0,
638 'status' => BADGE_STATUS_ACTIVE,
639 'version' => OPEN_BADGES_V2,
640 'language' => 'en',
641 'imageauthorname' => 'Image author',
642 'imageauthoremail' => 'author@example.com',
643 'imageauthorurl' => 'http://image.example.com/',
644 'imagecaption' => 'Image caption'
645 ], $params);
646 $record->id = $DB->insert_record('badge', $record);
648 return $record;
652 * Relate a badge.
654 * @param int $badgeid The badge ID.
655 * @param int $relatedbadgeid The related badge ID.
656 * @return object
658 protected function relate_badge(int $badgeid, int $relatedbadgeid) {
659 global $DB;
660 $record = (object) [
661 'badgeid' => $badgeid,
662 'relatedbadgeid' => $relatedbadgeid
664 $record->id = $DB->insert_record('badge_related', $record);
666 return $record;
670 * Align a badge.
672 * @param array $params Parameters.
673 * @return object
675 protected function align_badge(array $params = [], $suffix = '') {
676 global $DB;
677 $record = (object) array_merge([
678 'badgeid' => null,
679 'targetname' => "Alignment name" . $suffix,
680 'targeturl' => "http://issuer-url.domain.co.nz",
681 'targetdescription' => "Description" . $suffix,
682 'targetframework' => "Framework" . $suffix,
683 'targetcode' => "Code . $suffix"
684 ], $params);
685 $record->id = $DB->insert_record('badge_alignment', $record);
687 return $record;
691 * Endorse a badge.
693 * @param array $params Parameters.
694 * @return object
696 protected function endorse_badge(array $params = []) {
697 global $DB;
698 $record = (object) array_merge([
699 'badgeid' => null,
700 'issuername' => "External issuer name",
701 'issuerurl' => "http://issuer-url.domain.co.nz",
702 'issueremail' => "issuer@example.com",
703 'claimid' => "Claim ID",
704 'claimcomment' => "Claim comment",
705 'dateissued' => time()
706 ], $params);
707 $record->id = $DB->insert_record('badge_endorsement', $record);
709 return $record;
713 * Create a criteria of type badge.
715 * @param int $badgeid The badge ID.
716 * @param array $params Parameters.
717 * @return object
719 protected function create_criteria_badge($badgeid, array $params = []) {
720 $badge = new badge($badgeid);
721 if (empty($badge->criteria)) {
722 $overall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
723 $overall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ALL]);
726 $criteria = award_criteria::build([
727 'badgeid' => $badge->id,
728 'criteriatype' => BADGE_CRITERIA_TYPE_BADGE,
731 if (isset($params['badgeid'])) {
732 $params['badge_' . $params['badgeid']] = $params['badgeid'];
733 unset($params['badgeid']);
736 $criteria->save($params);
737 $badge = new badge($badgeid);
738 return $badge->criteria[BADGE_CRITERIA_TYPE_BADGE];
742 * Create a criteria of type manual.
744 * @param int $badgeid The badge ID.
745 * @param array $params Parameters.
746 * @return object
748 protected function create_criteria_manual($badgeid, array $params = []) {
749 global $DB;
751 $badge = new badge($badgeid);
752 if (empty($badge->criteria)) {
753 $overall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
754 $overall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ALL]);
757 $criteria = award_criteria::build([
758 'badgeid' => $badge->id,
759 'criteriatype' => BADGE_CRITERIA_TYPE_MANUAL,
762 $managerroleid = $DB->get_field_select('role', 'id', 'shortname = ?', ['manager'], IGNORE_MULTIPLE);
763 if (empty($params)) {
764 $params = [
765 'role_' . $managerroleid = $managerroleid
769 $criteria->save($params);
770 $badge = new badge($badgeid);
771 return $badge->criteria[BADGE_CRITERIA_TYPE_MANUAL];
775 * Create a badge issued.
777 * @param array $params Parameters.
778 * @return object
780 protected function create_issued(array $params = []) {
781 global $DB, $USER;
782 $record = (object) array_merge([
783 'badgeid' => null,
784 'userid' => null,
785 'uniquehash' => random_string(40),
786 'dateissued' => time(),
787 'dateexpire' => null,
788 'visible' => 1,
789 'issuernotified' => null,
790 ], $params);
791 $record->id = $DB->insert_record('badge_issued', $record);
792 return $record;
796 * Create a manual award.
798 * @param array $params Parameters.
799 * @return object
801 protected function create_manual_award(array $params = []) {
802 global $DB, $USER;
803 $record = (object) array_merge([
804 'badgeid' => null,
805 'recipientid' => null,
806 'issuerid' => $USER->id,
807 'issuerrole' => $DB->get_field_select('role', 'id', 'shortname = ?', ['manager'], IGNORE_MULTIPLE),
808 'datemet' => time()
809 ], $params);
810 $record->id = $DB->insert_record('badge_manual_award', $record);
811 return $record;