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 26 namespace core_contentbank\privacy; 27 28 use stdClass; 29 use context_system; 30 use context_coursecat; 31 use context_course; 32 use context_user; 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; 39 40 /** 41 * Unit tests for contentbank\classes\privacy\provider.php 42 * 43 * @copyright 2020 Carlos Escobedo <carlos@moodle.com> 44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 45 */ 46 class provider_test extends provider_testcase { 47 48 /** 49 * Setup to ensure that fixtures are loaded. 50 */ 51 public static function setupBeforeClass(): void { 52 global $CFG; 53 require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php'); 54 } 55 56 /** 57 * Test for provider::get_contexts_for_userid(). 58 */ 59 public function test_get_contexts_for_userid() { 60 61 $this->resetAfterTest(); 62 // Setup scenario. 63 $scenario = $this->setup_scenario(); 64 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, 73 $contextlistids); 74 $this->assertContainsEquals($scenario->coursecontext->id, $contextlistids); 75 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); 86 } 87 88 /** 89 * Test for provider::get_users_in_context(). 90 */ 91 public function test_get_users_in_context() { 92 93 $this->resetAfterTest(); 94 // Setup scenario. 95 $scenario = $this->setup_scenario(); 96 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()); 103 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); 107 108 $expected = [$scenario->manager->id, $scenario->teacher->id]; 109 sort($expected); 110 $actual = $userlist->get_userids(); 111 sort($actual); 112 $this->assertEquals($expected, $actual); 113 } 114 115 /** 116 * Test for provider::test_export_user_data(). 117 */ 118 public function test_export_user_data() { 119 120 $this->resetAfterTest(); 121 // Setup scenario. 122 $scenario = $this->setup_scenario(); 123 124 $subcontexts = [ 125 get_string('name', 'core_contentbank') 126 ]; 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)); 136 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)); 145 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)); 154 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)); 163 } 164 165 /** 166 * Test for provider::delete_data_for_all_users_in_context(). 167 */ 168 public function test_delete_data_for_all_users_in_context() { 169 global $DB; 170 171 $this->resetAfterTest(); 172 // Setup scenario. 173 $scenario = $this->setup_scenario(); 174 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). 179 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); 186 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); 193 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); 200 } 201 202 /** 203 * Test for provider::test_delete_data_for_users(). 204 */ 205 public function test_delete_data_for_users() { 206 global $DB; 207 208 $this->resetAfterTest(); 209 // Setup scenario. 210 $scenario = $this->setup_scenario(); 211 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). 216 217 // A list of users who has created content in Course Category Context. 218 $userlist1 = new userlist($scenario->coursecategorycontext, 219 'core_contentbank'); 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()); 224 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); 229 230 // Manager and Teacher should be. 231 $expected = [$scenario->manager->id, $scenario->teacher->id]; 232 sort($expected); 233 $actual = $userlist2->get_userids(); 234 sort($actual); 235 $this->assertEquals($expected, $actual); 236 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); 241 242 // Re-fetch users in course category context. 243 $userlist1 = new userlist($scenario->coursecategorycontext, 244 'core_contentbank'); 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); 253 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); 263 } 264 265 /** 266 * Test for provider::delete_data_for_user(). 267 */ 268 public function test_delete_data_for_user() { 269 global $DB; 270 271 $this->resetAfterTest(); 272 // Setup scenario. 273 $scenario = $this->setup_scenario(); 274 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). 279 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); 286 287 // After deletion, only 3 content for teacher should be present. 288 $count = $DB->count_records('contentbank_content'); 289 $this->assertEquals(3, $count); 290 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); 295 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); 302 303 // After deletion, no content should be present. 304 $count = $DB->count_records('contentbank_content'); 305 $this->assertEquals(0, $count); 306 } 307 308 /** 309 * Create a complex scenario to use into the tests. 310 * 311 * @return stdClass $scenario 312 */ 313 protected function setup_scenario() { 314 global $DB; 315 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); 320 321 $coursecategory = $this->getDataGenerator()->create_category(); 322 $coursecategorycontext = context_coursecat::instance($coursecategory->id); 323 324 $course = $this->getDataGenerator()->create_course(); 325 $coursecontext = context_course::instance($course->id); 326 $teacher = $this->getDataGenerator()->create_and_enrol($course, 327 'editingteacher'); 328 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'); 355 356 $scenario = new stdClass(); 357 $scenario->systemcontext = $systemcontext; 358 $scenario->coursecategorycontext = $coursecategorycontext; 359 $scenario->coursecontext = $coursecontext; 360 $scenario->manager = $manager; 361 $scenario->teacher = $teacher; 362 363 return $scenario; 364 } 365 366 /** 367 * Ensure that export_user_preferences returns no data if the user has not visited any content bank. 368 */ 369 public function test_export_user_preferences_no_pref() { 370 global $DB; 371 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); 376 377 provider::export_user_preferences($user->id); 378 $writer = writer::with_context(context_system::instance()); 379 $this->assertFalse($writer->has_any_data()); 380 } 381 382 /** 383 * Test for provider::test_export_user_preferences(). 384 */ 385 public function test_export_user_preferences() { 386 global $DB; 387 388 // Test setup. 389 $this->resetAfterTest(true); 390 $user = $this->getDataGenerator()->create_user(); 391 $this->setUser($user); 392 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()); 399 400 $prefs = $writer->get_user_preferences('core_contentbank'); 401 $this->assertCount(1, (array) $prefs); 402 $this->assertEquals(1, $prefs->core_contentbank_view_list->value); 403 $this->assertEquals( 404 get_string('privacy:request:preference:set', 'core_contentbank', (object) [ 405 'name' => 'core_contentbank_view_list', 406 'value' => $prefs->core_contentbank_view_list->value, 407 ]), 408 $prefs->core_contentbank_view_list->description 409 ); 410 } 411 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body