2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * Base class for unit tests for core_contentbank.
20 * @package core_contentbank
22 * @copyright 2020 Carlos Escobedo <carlos@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 namespace core_contentbank
;
30 use context_coursecat
;
33 use core_contentbank\privacy\provider
;
34 use core_privacy\local\request\approved_contextlist
;
35 use core_privacy\local\request\writer
;
36 use core_privacy\tests\provider_testcase
;
37 use core_privacy\local\request\userlist
;
38 use core_privacy\local\request\approved_userlist
;
41 * Unit tests for contentbank\classes\privacy\provider.php
43 * @copyright 2020 Carlos Escobedo <carlos@moodle.com>
44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46 class core_contentbank_privacy_testcase
extends provider_testcase
{
49 * Setup to ensure that fixtures are loaded.
51 public static function setupBeforeClass(): void
{
53 require_once($CFG->dirroot
. '/contentbank/tests/fixtures/testable_content.php');
57 * Test for provider::get_contexts_for_userid().
59 public function test_get_contexts_for_userid() {
61 $this->resetAfterTest();
63 $scenario = $this->setup_scenario();
65 // Testing againts Manager who has content in the three contexts.
66 $contextlist = provider
::get_contexts_for_userid($scenario->manager
->id
);
67 // There are three contexts in the list.
68 $contextlistids = $contextlist->get_contextids();
69 $this->assertCount(3, $contextlistids);
70 // Check the list against the expected list of contexts.
71 $this->assertContainsEquals($scenario->systemcontext
->id
, $contextlistids);
72 $this->assertContainsEquals($scenario->coursecategorycontext
->id
,
74 $this->assertContainsEquals($scenario->coursecontext
->id
, $contextlistids);
76 // Testing againts Teacher who has content in the one context.
77 $contextlist = provider
::get_contexts_for_userid($scenario->teacher
->id
);
78 // There are only one context in the list.
79 $contextlistids = $contextlist->get_contextids();
80 $this->assertCount(1, $contextlistids);
81 // Check the againts Course Context.
82 $this->assertContainsEquals($scenario->coursecontext
->id
, $contextlistids);
83 // And there is not a System and Course Category Context.
84 $this->assertNotContainsEquals($scenario->systemcontext
->id
, $contextlistids);
85 $this->assertNotContainsEquals($scenario->coursecategorycontext
->id
, $contextlistids);
89 * Test for provider::get_users_in_context().
91 public function test_get_users_in_context() {
93 $this->resetAfterTest();
95 $scenario = $this->setup_scenario();
97 // Get the userlist to Context System, only Manager will be there.
98 $userlist = new userlist($scenario->systemcontext
, 'core_contentbank');
99 provider
::get_users_in_context($userlist);
100 $this->assertEquals([$scenario->manager
->id
], $userlist->get_userids());
101 // Teacher will not be there.
102 $this->assertNotEquals([$scenario->teacher
->id
], $userlist->get_userids());
104 // Get the userlist to Context Course, Manager and Teacher will be there.
105 $userlist = new userlist($scenario->coursecontext
, 'core_contentbank');
106 provider
::get_users_in_context($userlist);
108 $expected = [$scenario->manager
->id
, $scenario->teacher
->id
];
110 $actual = $userlist->get_userids();
112 $this->assertEquals($expected, $actual);
116 * Test for provider::test_export_user_data().
118 public function test_export_user_data() {
120 $this->resetAfterTest();
122 $scenario = $this->setup_scenario();
125 get_string('name', 'core_contentbank')
127 // Get the data for the System Context.
128 $writer = writer
::with_context($scenario->systemcontext
);
129 $this->assertFalse($writer->has_any_data());
130 // Export data for Manager.
131 $this->export_context_data_for_user($scenario->manager
->id
,
132 $scenario->systemcontext
, 'core_contentbank');
133 $data = $writer->get_data($subcontexts);
134 $this->assertCount(3, (array) $data);
135 $this->assertCount(3, $writer->get_files($subcontexts));
137 // Get the data for the Course Categoy Context.
138 $writer = writer
::with_context($scenario->coursecategorycontext
);
139 // Export data for Manager.
140 $this->export_context_data_for_user($scenario->manager
->id
,
141 $scenario->coursecategorycontext
, 'core_contentbank');
142 $data = $writer->get_data($subcontexts);
143 $this->assertCount(2, (array) $data);
144 $this->assertCount(2, $writer->get_files($subcontexts));
146 // Get the data for the Course Context.
147 $writer = writer
::with_context($scenario->coursecontext
);
148 // Export data for Manager.
149 $this->export_context_data_for_user($scenario->manager
->id
,
150 $scenario->coursecontext
, 'core_contentbank');
151 $data = $writer->get_data($subcontexts);
152 $this->assertCount(2, (array) $data);
153 $this->assertCount(2, $writer->get_files($subcontexts));
155 // Export data for Teacher.
156 $writer = writer
::reset();
157 $writer = writer
::with_context($scenario->coursecontext
);
158 $this->export_context_data_for_user($scenario->teacher
->id
,
159 $scenario->coursecontext
, 'core_contentbank');
160 $data = $writer->get_data($subcontexts);
161 $this->assertCount(3, (array) $data);
162 $this->assertCount(3, $writer->get_files($subcontexts));
166 * Test for provider::delete_data_for_all_users_in_context().
168 public function test_delete_data_for_all_users_in_context() {
171 $this->resetAfterTest();
173 $scenario = $this->setup_scenario();
175 // Before delete data, we have 4 contents.
176 // - 3 in a system context.
177 // - 2 in a course category context.
178 // - 5 in a course context (2 by manager and 3 by teacher).
180 // Delete data based on system context.
181 provider
::delete_data_for_all_users_in_context($scenario->systemcontext
);
182 $count = $DB->count_records('contentbank_content');
183 // 3 content should be deleted.
184 // 7 contents should be remain.
185 $this->assertEquals(7, $count);
187 // Delete data based on course category context.
188 provider
::delete_data_for_all_users_in_context($scenario->coursecategorycontext
);
189 $count = $DB->count_records('contentbank_content');
190 // 2 contents should be deleted.
191 // 5 content should be remain.
192 $this->assertEquals(5, $count);
194 // Delete data based on course context.
195 provider
::delete_data_for_all_users_in_context($scenario->coursecontext
);
196 $count = $DB->count_records('contentbank_content');
197 // 5 content should be deleted.
198 // 0 content should be remain.
199 $this->assertEquals(0, $count);
203 * Test for provider::test_delete_data_for_users().
205 public function test_delete_data_for_users() {
208 $this->resetAfterTest();
210 $scenario = $this->setup_scenario();
212 // Before delete data, we have 4 contents.
213 // - 3 in a system context.
214 // - 2 in a course category context.
215 // - 5 in a course context (2 by manager and 3 by teacher).
217 // A list of users who has created content in Course Category Context.
218 $userlist1 = new userlist($scenario->coursecategorycontext
,
220 provider
::get_users_in_context($userlist1);
221 $this->assertCount(1, $userlist1);
222 // Only Manager should be.
223 $this->assertEquals([$scenario->manager
->id
], $userlist1->get_userids());
225 // A list of users who has created content in Course Context.
226 $userlist2 = new userlist($scenario->coursecontext
, 'core_contentbank');
227 provider
::get_users_in_context($userlist2);
228 $this->assertCount(2, $userlist2);
230 // Manager and Teacher should be.
231 $expected = [$scenario->manager
->id
, $scenario->teacher
->id
];
233 $actual = $userlist2->get_userids();
235 $this->assertEquals($expected, $actual);
237 // Convert $userlist1 into an approved_contextlist.
238 $approvedlist1 = new approved_userlist($scenario->coursecategorycontext
, 'core_contentbank', $userlist1->get_userids());
239 // Delete data for users in course category context.
240 provider
::delete_data_for_users($approvedlist1);
242 // Re-fetch users in course category context.
243 $userlist1 = new userlist($scenario->coursecategorycontext
,
245 provider
::get_users_in_context($userlist1);
246 // The user data in course category context should be deleted.
247 $this->assertCount(0, $userlist1);
248 // Re-fetch users in course category context.
249 $userlist2 = new userlist($scenario->coursecontext
, 'core_contentbank');
250 provider
::get_users_in_context($userlist2);
251 // The user data in course context should be still present.
252 $this->assertCount(2, $userlist2);
254 // Convert $userlist2 into an approved_contextlist.
255 $approvedlist2 = new approved_userlist($scenario->coursecontext
,
256 'core_contentbank', $userlist2->get_userids());
257 // Delete data for users in course context.
258 provider
::delete_data_for_users($approvedlist2);
259 $userlist2 = new userlist($scenario->coursecontext
, 'core_contentbank');
260 provider
::get_users_in_context($userlist2);
261 // The user data in course context should be deleted.
262 $this->assertCount(0, $userlist2);
266 * Test for provider::delete_data_for_user().
268 public function test_delete_data_for_user() {
271 $this->resetAfterTest();
273 $scenario = $this->setup_scenario();
275 // Before delete data, we have 4 contents.
276 // - 3 in a system context.
277 // - 2 in a course category context.
278 // - 5 in a course context (2 by manager and 3 by teacher).
280 // Get all the context for Manager.
281 $contextlist = provider
::get_contexts_for_userid($scenario->manager
->id
);
282 $approvedcontextlist = new approved_contextlist($scenario->manager
,
283 'core_contentbank', $contextlist->get_contextids());
284 // Delete all the data created by the Manager in all the contexts.
285 provider
::delete_data_for_user($approvedcontextlist);
287 // After deletion, only 3 content for teacher should be present.
288 $count = $DB->count_records('contentbank_content');
289 $this->assertEquals(3, $count);
291 // Confirm that the remaining content was created by the teacher.
292 $count = $DB->count_records('contentbank_content',
293 ['usercreated' => $scenario->teacher
->id
]);
294 $this->assertEquals(3, $count);
296 // Get all the context for Teacher.
297 $contextlist = provider
::get_contexts_for_userid($scenario->teacher
->id
);
298 $approvedcontextlist = new approved_contextlist($scenario->teacher
,
299 'core_contentbank', $contextlist->get_contextids());
300 // Delete all the data created by the Teacher in all the contexts.
301 provider
::delete_data_for_user($approvedcontextlist);
303 // After deletion, no content should be present.
304 $count = $DB->count_records('contentbank_content');
305 $this->assertEquals(0, $count);
309 * Create a complex scenario to use into the tests.
311 * @return stdClass $scenario
313 protected function setup_scenario() {
316 $systemcontext = context_system
::instance();
317 $manager = $this->getDataGenerator()->create_user();
318 $managerroleid = $DB->get_field('role', 'id', ['shortname' => 'manager']);
319 $this->getDataGenerator()->role_assign($managerroleid, $manager->id
);
321 $coursecategory = $this->getDataGenerator()->create_category();
322 $coursecategorycontext = context_coursecat
::instance($coursecategory->id
);
324 $course = $this->getDataGenerator()->create_course();
325 $coursecontext = context_course
::instance($course->id
);
326 $teacher = $this->getDataGenerator()->create_and_enrol($course,
329 // Add some content to the content bank.
330 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
331 // Add contents by Manager in Context System.
332 $records = $generator->generate_contentbank_data('contenttype_testable',
333 1, $manager->id
, $systemcontext, false, 'systemtestfile1.h5p');
334 $records = $generator->generate_contentbank_data('contenttype_testable',
335 1, $manager->id
, $systemcontext, false, 'systemtestfile2.h5p');
336 $records = $generator->generate_contentbank_data('contenttype_testable',
337 1, $manager->id
, $systemcontext, false, 'systemtestfile3.h5p');
338 // Add contents by Manager in Context Course Category.
339 $records = $generator->generate_contentbank_data('contenttype_testable',
340 1, $manager->id
, $coursecategorycontext, false, 'coursecattestfile1.h5p');
341 $records = $generator->generate_contentbank_data('contenttype_testable',
342 1, $manager->id
, $coursecategorycontext, false, 'coursecattestfile2.h5p');
343 // Add contents by Manager in Context Course.
344 $records = $generator->generate_contentbank_data('contenttype_testable',
345 1, $manager->id
, $coursecontext, false, 'coursetestfile1.h5p');
346 $records = $generator->generate_contentbank_data('contenttype_testable',
347 1, $manager->id
, $coursecontext, false, 'coursetestfile2.h5p');
348 // Add contents by Teacher.
349 $records = $generator->generate_contentbank_data('contenttype_testable',
350 1, $teacher->id
, $coursecontext, false, 'courseteacherfile1.h5p');
351 $records = $generator->generate_contentbank_data('contenttype_testable',
352 1, $teacher->id
, $coursecontext, false, 'courseteacherfile2.h5p');
353 $records = $generator->generate_contentbank_data('contenttype_testable',
354 1, $teacher->id
, $coursecontext, false, 'courseteacherfile3.h5p');
356 $scenario = new stdClass();
357 $scenario->systemcontext
= $systemcontext;
358 $scenario->coursecategorycontext
= $coursecategorycontext;
359 $scenario->coursecontext
= $coursecontext;
360 $scenario->manager
= $manager;
361 $scenario->teacher
= $teacher;
367 * Ensure that export_user_preferences returns no data if the user has not visited any content bank.
369 public function test_export_user_preferences_no_pref() {
372 $this->resetAfterTest();
373 $user = $this->getDataGenerator()->create_user();
374 $managerroleid = $DB->get_field('role', 'id', ['shortname' => 'manager']);
375 $this->getDataGenerator()->role_assign($managerroleid, $user->id
);
377 provider
::export_user_preferences($user->id
);
378 $writer = writer
::with_context(context_system
::instance());
379 $this->assertFalse($writer->has_any_data());
383 * Test for provider::test_export_user_preferences().
385 public function test_export_user_preferences() {
389 $this->resetAfterTest(true);
390 $user = $this->getDataGenerator()->create_user();
391 $this->setUser($user);
393 set_user_preference('core_contentbank_view_list', 1);
394 // Test the user preferences export contains 1 user preference record for the User.
395 provider
::export_user_preferences($user->id
);
396 $contextuser = context_user
::instance($user->id
);
397 $writer = writer
::with_context($contextuser);
398 $this->assertTrue($writer->has_any_data());
400 $prefs = $writer->get_user_preferences('core_contentbank');
401 $this->assertCount(1, (array) $prefs);
402 $this->assertEquals(1, $prefs->core_contentbank_view_list
->value
);
404 get_string('privacy:request:preference:set', 'core_contentbank', (object) [
405 'name' => 'core_contentbank_view_list',
406 'value' => $prefs->core_contentbank_view_list
->value
,
408 $prefs->core_contentbank_view_list
->description