MDL-68483 contentbank: improve search API
[moodle.git] / contentbank / tests / privacy_test.php
CommitLineData
aeacd6c8 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 * Base class for unit tests for core_contentbank.
19 *
20 * @package core_contentbank
21 * @category test
22 * @copyright 2020 Carlos Escobedo <carlos@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26namespace core_contentbank;
27
28defined('MOODLE_INTERNAL') || die();
29
30use stdClass;
31use context_system;
32use context_coursecat;
33use context_course;
34use core_contentbank\privacy\provider;
35use core_privacy\local\request\approved_contextlist;
36use core_privacy\local\request\writer;
37use core_privacy\tests\provider_testcase;
38use core_privacy\local\request\userlist;
39use core_privacy\local\request\approved_userlist;
40
41/**
42 * Unit tests for contentbank\classes\privacy\provider.php
43 *
44 * @copyright 2020 Carlos Escobedo <carlos@moodle.com>
45 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46 */
47class core_contentbank_privacy_testcase extends provider_testcase {
48
49 /**
50 * Setup to ensure that fixtures are loaded.
51 */
52 public static function setupBeforeClass(): void {
53 global $CFG;
54 require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
55 }
56
57 /**
58 * Test for provider::get_contexts_for_userid().
59 */
60 public function test_get_contexts_for_userid() {
61
62 $this->resetAfterTest();
63 // Setup scenario.
64 $scenario = $this->setup_scenario();
65
66 // Testing againts Manager who has content in the three contexts.
67 $contextlist = provider::get_contexts_for_userid($scenario->manager->id);
68 // There are three contexts in the list.
69 $contextlistids = $contextlist->get_contextids();
70 $this->assertCount(3, $contextlistids);
71 // Check the list against the expected list of contexts.
72 $this->assertContains($scenario->systemcontext->id, $contextlistids);
73 $this->assertContains($scenario->coursecategorycontext->id,
74 $contextlistids);
75 $this->assertContains($scenario->coursecontext->id, $contextlistids);
76
77 // Testing againts Teacher who has content in the one context.
78 $contextlist = provider::get_contexts_for_userid($scenario->teacher->id);
79 // There are only one context in the list.
80 $contextlistids = $contextlist->get_contextids();
81 $this->assertCount(1, $contextlistids);
82 // Check the againts Course Context.
83 $this->assertContains($scenario->coursecontext->id, $contextlistids);
84 // And there is not a System and Course Category Context.
85 $this->assertNotContains($scenario->systemcontext->id, $contextlistids);
86 $this->assertNotContains($scenario->coursecategorycontext->id, $contextlistids);
87 }
88
89 /**
90 * Test for provider::get_users_in_context().
91 */
92 public function test_get_users_in_context() {
93
94 $this->resetAfterTest();
95 // Setup scenario.
96 $scenario = $this->setup_scenario();
97
98 // Get the userlist to Context System, only Manager will be there.
99 $userlist = new userlist($scenario->systemcontext, 'core_contentbank');
100 provider::get_users_in_context($userlist);
101 $this->assertEquals([$scenario->manager->id], $userlist->get_userids());
102 // Teacher will not be there.
103 $this->assertNotEquals([$scenario->teacher->id], $userlist->get_userids());
104
105 // Get the userlist to Context Course, Manager and Teacher will be there.
106 $userlist = new userlist($scenario->coursecontext, 'core_contentbank');
107 provider::get_users_in_context($userlist);
9e0c40d1
AN
108
109 $expected = [$scenario->manager->id, $scenario->teacher->id];
110 sort($expected);
111 $actual = $userlist->get_userids();
112 sort($actual);
113 $this->assertEquals($expected, $actual);
aeacd6c8 114 }
115
116 /**
117 * Test for provider::test_export_user_data().
118 */
119 public function test_export_user_data() {
120
121 $this->resetAfterTest();
122 // Setup scenario.
123 $scenario = $this->setup_scenario();
124
125 $subcontexts = [
126 get_string('name', 'core_contentbank')
127 ];
128 // Get the data for the System Context.
129 $writer = writer::with_context($scenario->systemcontext);
130 $this->assertFalse($writer->has_any_data());
131 // Export data for Manager.
132 $this->export_context_data_for_user($scenario->manager->id,
133 $scenario->systemcontext, 'core_contentbank');
134 $data = $writer->get_data($subcontexts);
135 $this->assertCount(3, (array) $data);
136 $this->assertCount(3, $writer->get_files($subcontexts));
137
138 // Get the data for the Course Categoy Context.
139 $writer = writer::with_context($scenario->coursecategorycontext);
140 // Export data for Manager.
141 $this->export_context_data_for_user($scenario->manager->id,
142 $scenario->coursecategorycontext, 'core_contentbank');
143 $data = $writer->get_data($subcontexts);
144 $this->assertCount(2, (array) $data);
145 $this->assertCount(2, $writer->get_files($subcontexts));
146
147 // Get the data for the Course Context.
148 $writer = writer::with_context($scenario->coursecontext);
149 // Export data for Manager.
150 $this->export_context_data_for_user($scenario->manager->id,
151 $scenario->coursecontext, 'core_contentbank');
152 $data = $writer->get_data($subcontexts);
153 $this->assertCount(2, (array) $data);
154 $this->assertCount(2, $writer->get_files($subcontexts));
155
156 // Export data for Teacher.
157 $writer = writer::reset();
158 $writer = writer::with_context($scenario->coursecontext);
159 $this->export_context_data_for_user($scenario->teacher->id,
160 $scenario->coursecontext, 'core_contentbank');
161 $data = $writer->get_data($subcontexts);
162 $this->assertCount(3, (array) $data);
163 $this->assertCount(3, $writer->get_files($subcontexts));
164 }
165
166 /**
167 * Test for provider::delete_data_for_all_users_in_context().
168 */
169 public function test_delete_data_for_all_users_in_context() {
170 global $DB;
171
172 $this->resetAfterTest();
173 // Setup scenario.
174 $scenario = $this->setup_scenario();
175
176 // Before delete data, we have 4 contents.
177 // - 3 in a system context.
178 // - 2 in a course category context.
179 // - 5 in a course context (2 by manager and 3 by teacher).
180
181 // Delete data based on system context.
182 provider::delete_data_for_all_users_in_context($scenario->systemcontext);
183 $count = $DB->count_records('contentbank_content');
184 // 3 content should be deleted.
185 // 7 contents should be remain.
186 $this->assertEquals(7, $count);
187
188 // Delete data based on course category context.
189 provider::delete_data_for_all_users_in_context($scenario->coursecategorycontext);
190 $count = $DB->count_records('contentbank_content');
191 // 2 contents should be deleted.
192 // 5 content should be remain.
193 $this->assertEquals(5, $count);
194
195 // Delete data based on course context.
196 provider::delete_data_for_all_users_in_context($scenario->coursecontext);
197 $count = $DB->count_records('contentbank_content');
198 // 5 content should be deleted.
199 // 0 content should be remain.
200 $this->assertEquals(0, $count);
201 }
202
203 /**
204 * Test for provider::test_delete_data_for_users().
205 */
206 public function test_delete_data_for_users() {
207 global $DB;
208
209 $this->resetAfterTest();
210 // Setup scenario.
211 $scenario = $this->setup_scenario();
212
213 // Before delete data, we have 4 contents.
214 // - 3 in a system context.
215 // - 2 in a course category context.
216 // - 5 in a course context (2 by manager and 3 by teacher).
217
218 // A list of users who has created content in Course Category Context.
219 $userlist1 = new userlist($scenario->coursecategorycontext,
220 'core_contentbank');
221 provider::get_users_in_context($userlist1);
222 $this->assertCount(1, $userlist1);
223 // Only Manager should be.
224 $this->assertEquals([$scenario->manager->id], $userlist1->get_userids());
225
226 // A list of users who has created content in Course Context.
227 $userlist2 = new userlist($scenario->coursecontext, 'core_contentbank');
228 provider::get_users_in_context($userlist2);
229 $this->assertCount(2, $userlist2);
9e0c40d1 230
aeacd6c8 231 // Manager and Teacher should be.
9e0c40d1
AN
232 $expected = [$scenario->manager->id, $scenario->teacher->id];
233 sort($expected);
234 $actual = $userlist2->get_userids();
235 sort($actual);
236 $this->assertEquals($expected, $actual);
aeacd6c8 237
238 // Convert $userlist1 into an approved_contextlist.
239 $approvedlist1 = new approved_userlist($scenario->coursecategorycontext, 'core_contentbank', $userlist1->get_userids());
240 // Delete data for users in course category context.
241 provider::delete_data_for_users($approvedlist1);
242
243 // Re-fetch users in course category context.
244 $userlist1 = new userlist($scenario->coursecategorycontext,
245 'core_contentbank');
246 provider::get_users_in_context($userlist1);
247 // The user data in course category context should be deleted.
248 $this->assertCount(0, $userlist1);
249 // Re-fetch users in course category context.
250 $userlist2 = new userlist($scenario->coursecontext, 'core_contentbank');
251 provider::get_users_in_context($userlist2);
252 // The user data in course context should be still present.
253 $this->assertCount(2, $userlist2);
254
255 // Convert $userlist2 into an approved_contextlist.
256 $approvedlist2 = new approved_userlist($scenario->coursecontext,
257 'core_contentbank', $userlist2->get_userids());
258 // Delete data for users in course context.
259 provider::delete_data_for_users($approvedlist2);
260 $userlist2 = new userlist($scenario->coursecontext, 'core_contentbank');
261 provider::get_users_in_context($userlist2);
262 // The user data in course context should be deleted.
263 $this->assertCount(0, $userlist2);
264 }
265
266 /**
267 * Test for provider::delete_data_for_user().
268 */
269 public function test_delete_data_for_user() {
270 global $DB;
271
272 $this->resetAfterTest();
273 // Setup scenario.
274 $scenario = $this->setup_scenario();
275
276 // Before delete data, we have 4 contents.
277 // - 3 in a system context.
278 // - 2 in a course category context.
279 // - 5 in a course context (2 by manager and 3 by teacher).
280
281 // Get all the context for Manager.
282 $contextlist = provider::get_contexts_for_userid($scenario->manager->id);
283 $approvedcontextlist = new approved_contextlist($scenario->manager,
284 'core_contentbank', $contextlist->get_contextids());
285 // Delete all the data created by the Manager in all the contexts.
286 provider::delete_data_for_user($approvedcontextlist);
287
288 // After deletion, only 3 content for teacher should be present.
289 $count = $DB->count_records('contentbank_content');
290 $this->assertEquals(3, $count);
291
292 // Confirm that the remaining content was created by the teacher.
293 $count = $DB->count_records('contentbank_content',
294 ['usercreated' => $scenario->teacher->id]);
295 $this->assertEquals(3, $count);
296
297 // Get all the context for Teacher.
298 $contextlist = provider::get_contexts_for_userid($scenario->teacher->id);
299 $approvedcontextlist = new approved_contextlist($scenario->teacher,
300 'core_contentbank', $contextlist->get_contextids());
301 // Delete all the data created by the Teacher in all the contexts.
302 provider::delete_data_for_user($approvedcontextlist);
303
304 // After deletion, no content should be present.
305 $count = $DB->count_records('contentbank_content');
306 $this->assertEquals(0, $count);
307 }
308
309 /**
310 * Create a complex scenario to use into the tests.
311 *
312 * @return stdClass $scenario
313 */
314 protected function setup_scenario() {
315 global $DB;
316
317 $systemcontext = context_system::instance();
318 $manager = $this->getDataGenerator()->create_user();
319 $managerroleid = $DB->get_field('role', 'id', ['shortname' => 'manager']);
320 $this->getDataGenerator()->role_assign($managerroleid, $manager->id);
321
322 $coursecategory = $this->getDataGenerator()->create_category();
323 $coursecategorycontext = context_coursecat::instance($coursecategory->id);
324
325 $course = $this->getDataGenerator()->create_course();
326 $coursecontext = context_course::instance($course->id);
327 $teacher = $this->getDataGenerator()->create_and_enrol($course,
328 'editingteacher');
329
330 // Add some content to the content bank.
331 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
332 // Add contents by Manager in Context System.
333 $records = $generator->generate_contentbank_data('contenttype_testable',
334 1, $manager->id, $systemcontext, false, 'systemtestfile1.h5p');
335 $records = $generator->generate_contentbank_data('contenttype_testable',
336 1, $manager->id, $systemcontext, false, 'systemtestfile2.h5p');
337 $records = $generator->generate_contentbank_data('contenttype_testable',
338 1, $manager->id, $systemcontext, false, 'systemtestfile3.h5p');
339 // Add contents by Manager in Context Course Category.
340 $records = $generator->generate_contentbank_data('contenttype_testable',
341 1, $manager->id, $coursecategorycontext, false, 'coursecattestfile1.h5p');
342 $records = $generator->generate_contentbank_data('contenttype_testable',
343 1, $manager->id, $coursecategorycontext, false, 'coursecattestfile2.h5p');
344 // Add contents by Manager in Context Course.
345 $records = $generator->generate_contentbank_data('contenttype_testable',
346 1, $manager->id, $coursecontext, false, 'coursetestfile1.h5p');
347 $records = $generator->generate_contentbank_data('contenttype_testable',
348 1, $manager->id, $coursecontext, false, 'coursetestfile2.h5p');
349 // Add contents by Teacher.
350 $records = $generator->generate_contentbank_data('contenttype_testable',
351 1, $teacher->id, $coursecontext, false, 'courseteacherfile1.h5p');
352 $records = $generator->generate_contentbank_data('contenttype_testable',
353 1, $teacher->id, $coursecontext, false, 'courseteacherfile2.h5p');
354 $records = $generator->generate_contentbank_data('contenttype_testable',
355 1, $teacher->id, $coursecontext, false, 'courseteacherfile3.h5p');
356
357 $scenario = new stdClass();
358 $scenario->systemcontext = $systemcontext;
359 $scenario->coursecategorycontext = $coursecategorycontext;
360 $scenario->coursecontext = $coursecontext;
361 $scenario->manager = $manager;
362 $scenario->teacher = $teacher;
363
364 return $scenario;
365 }
366}