See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310]
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 * Unit tests for privacy. 19 * 20 * @package search_simpledb 21 * @copyright 2018 David MonllaĆ³ {@link http://www.davidmonllao.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 use \search_simpledb\privacy\provider; 26 use core_privacy\local\request\transform; 27 use core_privacy\local\request\writer; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php'); 33 require_once($CFG->dirroot . '/search/tests/fixtures/mock_search_area.php'); 34 35 /** 36 * Unit tests for privacy. 37 * 38 * @package search_simpledb 39 * @copyright 2018 David MonllaĆ³ {@link http://www.davidmonllao.com} 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class privacy_model_testcase extends \core_privacy\tests\provider_testcase { 43 44 public function setUp() { 45 global $DB; 46 47 if ($this->requires_manual_index_update()) { 48 // We need to update fulltext index manually, which requires an alter table statement. 49 $this->preventResetByRollback(); 50 } 51 52 $this->resetAfterTest(); 53 set_config('enableglobalsearch', true); 54 55 // Inject search_simpledb engine into the testable core search as we need to add the mock 56 // search component to it. 57 58 $this->engine = new \search_simpledb\engine(); 59 $this->search = testable_core_search::instance($this->engine); 60 $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area'); 61 $this->search->add_search_area($areaid, new core_mocksearch\search\mock_search_area()); 62 63 $this->generator = self::getDataGenerator()->get_plugin_generator('core_search'); 64 $this->generator->setup(); 65 66 $this->c1 = $this->getDataGenerator()->create_course(); 67 $this->c2 = $this->getDataGenerator()->create_course(); 68 69 $this->c1context = \context_course::instance($this->c1->id); 70 $this->c2context = \context_course::instance($this->c2->id); 71 72 $this->u1 = $this->getDataGenerator()->create_user(); 73 $this->u2 = $this->getDataGenerator()->create_user(); 74 75 $this->getDataGenerator()->enrol_user($this->u1->id, $this->c1->id, 'student'); 76 $this->getDataGenerator()->enrol_user($this->u1->id, $this->c2->id, 'student'); 77 $this->getDataGenerator()->enrol_user($this->u2->id, $this->c1->id, 'student'); 78 $this->getDataGenerator()->enrol_user($this->u2->id, $this->c2->id, 'student'); 79 80 $record = (object)[ 81 'userid' => $this->u1->id, 82 'contextid' => $this->c1context->id, 83 'title' => 'vi', 84 'content' => 'va', 85 'description1' => 'san', 86 'description2' => 'jose' 87 ]; 88 $this->generator->create_record($record); 89 $this->generator->create_record((object)['userid' => $this->u1->id, 'contextid' => $this->c2context->id]); 90 $this->generator->create_record((object)['userid' => $this->u2->id, 'contextid' => $this->c2context->id]); 91 $this->generator->create_record((object)['userid' => $this->u2->id, 'contextid' => $this->c1context->id]); 92 $this->generator->create_record((object)['owneruserid' => $this->u1->id, 'contextid' => $this->c1context->id]); 93 $this->generator->create_record((object)['owneruserid' => $this->u1->id, 'contextid' => $this->c2context->id]); 94 $this->generator->create_record((object)['owneruserid' => $this->u2->id, 'contextid' => $this->c1context->id]); 95 $this->generator->create_record((object)['owneruserid' => $this->u2->id, 'contextid' => $this->c2context->id]); 96 $this->search->index(); 97 98 $this->setAdminUser(); 99 } 100 101 /** 102 * tearDown 103 * 104 * @return void 105 */ 106 public function tearDown() { 107 // Call parent tearDown() first. 108 parent::tearDown(); 109 110 // For unit tests before PHP 7, teardown is called even on skip. So only do our teardown if we did setup. 111 if ($this->generator) { 112 // Moodle DML freaks out if we don't teardown the temp table after each run. 113 $this->generator->teardown(); 114 $this->generator = null; 115 } 116 } 117 118 /** 119 * Test fetching contexts for a given user ID. 120 */ 121 public function test_get_contexts_for_userid() { 122 // Ensure both contexts are found for both users. 123 $expected = [$this->c1context->id, $this->c2context->id]; 124 sort($expected); 125 126 // User 1. 127 $contextlist = provider::get_contexts_for_userid($this->u1->id); 128 $this->assertCount(2, $contextlist); 129 130 $actual = $contextlist->get_contextids(); 131 sort($actual); 132 $this->assertEquals($expected, $actual); 133 134 // User 2. 135 $contextlist = provider::get_contexts_for_userid($this->u2->id); 136 $this->assertCount(2, $contextlist); 137 138 $actual = $contextlist->get_contextids(); 139 sort($actual); 140 $this->assertEquals($expected, $actual); 141 } 142 143 /** 144 * Test fetching user IDs for a given context. 145 */ 146 public function test_get_users_in_context() { 147 $component = 'search_simpledb'; 148 149 // Ensure both users are found for both contexts. 150 $expected = [$this->u1->id, $this->u2->id]; 151 sort($expected); 152 153 // User 1. 154 $userlist = new \core_privacy\local\request\userlist($this->c1context, $component); 155 provider::get_users_in_context($userlist); 156 $this->assertCount(2, $userlist); 157 158 $actual = $userlist->get_userids(); 159 sort($actual); 160 $this->assertEquals($expected, $actual); 161 162 // User 2. 163 $userlist = new \core_privacy\local\request\userlist($this->c2context, $component); 164 provider::get_users_in_context($userlist); 165 $this->assertCount(2, $userlist); 166 167 $actual = $userlist->get_userids(); 168 sort($actual); 169 $this->assertEquals($expected, $actual); 170 } 171 172 /** 173 * Test export user data. 174 * 175 * @return null 176 */ 177 public function test_export_user_data() { 178 global $DB; 179 180 $contextlist = new \core_privacy\local\request\approved_contextlist($this->u1, 'search_simpledb', 181 [$this->c1context->id]); 182 provider::export_user_data($contextlist); 183 $writer = \core_privacy\local\request\writer::with_context($this->c1context); 184 $this->assertTrue($writer->has_any_data()); 185 $u1c1 = $DB->get_record('search_simpledb_index', ['userid' => $this->u1->id, 'contextid' => $this->c1context->id]); 186 $data = $writer->get_data([get_string('search', 'search'), $u1c1->docid]); 187 188 $this->assertEquals($this->c1context->get_context_name(true, true), $data->context); 189 $this->assertEquals('vi', $data->title); 190 $this->assertEquals('va', $data->content); 191 $this->assertEquals('san', $data->description1); 192 $this->assertEquals('jose', $data->description2); 193 } 194 195 /** 196 * Test delete search for context. 197 * 198 * @return null 199 */ 200 public function test_delete_data_for_all_users() { 201 global $DB; 202 203 $this->assertEquals(8, $DB->count_records('search_simpledb_index')); 204 205 provider::delete_data_for_all_users_in_context($this->c1context); 206 $this->assertEquals(0, $DB->count_records('search_simpledb_index', ['contextid' => $this->c1context->id])); 207 $this->assertEquals(4, $DB->count_records('search_simpledb_index')); 208 209 $u2context = \context_user::instance($this->u2->id); 210 provider::delete_data_for_all_users_in_context($u2context); 211 $this->assertEquals(0, $DB->count_records('search_simpledb_index', ['contextid' => $u2context->id])); 212 $this->assertEquals(2, $DB->count_records('search_simpledb_index')); 213 } 214 215 /** 216 * Test delete search for user. 217 * 218 * @return null 219 */ 220 public function test_delete_data_for_user() { 221 global $DB; 222 223 $contextlist = new \core_privacy\local\request\approved_contextlist($this->u1, 'search_simpledb', 224 [$this->c1context->id]); 225 provider::delete_data_for_user($contextlist); 226 $select = 'contextid = :contextid AND (owneruserid = :owneruserid OR userid = :userid)'; 227 $params = ['contextid' => $this->c1context->id, 'owneruserid' => $this->u1->id, 'userid' => $this->u1->id]; 228 $this->assertEquals(0, $DB->count_records_select('search_simpledb_index', $select, $params)); 229 $this->assertEquals(2, $DB->count_records('search_simpledb_index', ['contextid' => $this->c1context->id])); 230 $this->assertEquals(6, $DB->count_records('search_simpledb_index')); 231 232 $contextlist = new \core_privacy\local\request\approved_contextlist($this->u2, 'search_simpledb', 233 [$this->c2context->id]); 234 provider::delete_data_for_user($contextlist); 235 $select = 'contextid = :contextid AND (owneruserid = :owneruserid OR userid = :userid)'; 236 $params = ['contextid' => $this->c2context->id, 'owneruserid' => $this->u2->id, 'userid' => $this->u2->id]; 237 $this->assertEquals(0, $DB->count_records_select('search_simpledb_index', $select, $params)); 238 $this->assertEquals(2, $DB->count_records('search_simpledb_index', ['contextid' => $this->c2context->id])); 239 $this->assertEquals(4, $DB->count_records('search_simpledb_index')); 240 } 241 242 /** 243 * Test deleting data for an approved userlist. 244 */ 245 public function test_delete_data_for_users() { 246 global $DB; 247 $component = 'search_simpledb'; 248 $select = 'contextid = :contextid AND (owneruserid = :owneruserid OR userid = :userid)'; 249 250 // Ensure expected amount of data for both users exists in each context. 251 $this->assertEquals(4, $DB->count_records('search_simpledb_index', ['contextid' => $this->c1context->id])); 252 $this->assertEquals(4, $DB->count_records('search_simpledb_index', ['contextid' => $this->c2context->id])); 253 254 // Delete user 1's data in context 1. 255 $approveduserids = [$this->u1->id]; 256 $approvedlist = new \core_privacy\local\request\approved_userlist($this->c1context, $component, $approveduserids); 257 provider::delete_data_for_users($approvedlist); 258 259 $params = ['contextid' => $this->c1context->id, 'owneruserid' => $this->u1->id, 'userid' => $this->u1->id]; 260 $this->assertEquals(0, $DB->count_records_select('search_simpledb_index', $select, $params)); 261 262 // Ensure user 2's data in context 1 is retained. 263 $params = ['contextid' => $this->c1context->id, 'owneruserid' => $this->u2->id, 'userid' => $this->u2->id]; 264 $this->assertEquals(2, $DB->count_records_select('search_simpledb_index', $select, $params)); 265 266 // Ensure both users' data in context 2 is retained. 267 $params = ['contextid' => $this->c2context->id, 'owneruserid' => $this->u1->id, 'userid' => $this->u1->id]; 268 $this->assertEquals(2, $DB->count_records_select('search_simpledb_index', $select, $params)); 269 $params = ['contextid' => $this->c2context->id, 'owneruserid' => $this->u2->id, 'userid' => $this->u2->id]; 270 $this->assertEquals(2, $DB->count_records_select('search_simpledb_index', $select, $params)); 271 } 272 273 /** 274 * Mssql with fulltext support requires manual updates. 275 * 276 * @return bool 277 */ 278 private function requires_manual_index_update() { 279 global $DB; 280 return ($DB->get_dbfamily() === 'mssql' && $DB->is_fulltext_search_supported()); 281 } 282 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body