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