Rev 11 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Unit tests for privacy.** @package search_simpledb* @copyright 2018 David Monllaó {@link http://www.davidmonllao.com}* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace search_simpledb\privacy;use search_simpledb\privacy\provider;use core_privacy\local\request\transform;use core_privacy\local\request\writer;defined('MOODLE_INTERNAL') || die();global $CFG;require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');require_once($CFG->dirroot . '/search/tests/fixtures/mock_search_area.php');/*** Unit tests for privacy.** @package search_simpledb* @copyright 2018 David Monllaó {@link http://www.davidmonllao.com}* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/final class provider_test extends \core_privacy\tests\provider_testcase {/** @var \search_simpledb\engine database engine. */protected $engine;/** @var \testable_core_search core search class adapted to unit test. */protected $search;/** @var \core_search_generator core search generator class adapted to unit test. */protected $generator = null;/** @var \stdClass course record.*/protected $c1;/** @var \stdClass course record.*/protected $c2;/** @var \context_course context instance. */protected $c1context;/** @var \context_course context instance. */protected $c2context;/** @var \stdClass user record. */protected $u1;/** @var \stdClass user record. */protected $u2;public function setUp(): void {global $DB;parent::setUp();if ($this->requires_manual_index_update()) {// We need to update fulltext index manually, which requires an alter table statement.$this->preventResetByRollback();}$this->resetAfterTest();set_config('enableglobalsearch', true);// Inject search_simpledb engine into the testable core search as we need to add the mock// search component to it.$this->engine = new \search_simpledb\engine();$this->search = \testable_core_search::instance($this->engine);$areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');$this->search->add_search_area($areaid, new \core_mocksearch\search\mock_search_area());$this->generator = self::getDataGenerator()->get_plugin_generator('core_search');$this->generator->setup();$this->c1 = $this->getDataGenerator()->create_course();$this->c2 = $this->getDataGenerator()->create_course();$this->c1context = \context_course::instance($this->c1->id);$this->c2context = \context_course::instance($this->c2->id);$this->u1 = $this->getDataGenerator()->create_user();$this->u2 = $this->getDataGenerator()->create_user();$this->getDataGenerator()->enrol_user($this->u1->id, $this->c1->id, 'student');$this->getDataGenerator()->enrol_user($this->u1->id, $this->c2->id, 'student');$this->getDataGenerator()->enrol_user($this->u2->id, $this->c1->id, 'student');$this->getDataGenerator()->enrol_user($this->u2->id, $this->c2->id, 'student');$record = (object)['userid' => $this->u1->id,'contextid' => $this->c1context->id,'title' => 'vi','content' => 'va','description1' => 'san','description2' => 'jose'];$this->generator->create_record($record);$this->generator->create_record((object)['userid' => $this->u1->id, 'contextid' => $this->c2context->id]);$this->generator->create_record((object)['userid' => $this->u2->id, 'contextid' => $this->c2context->id]);$this->generator->create_record((object)['userid' => $this->u2->id, 'contextid' => $this->c1context->id]);$this->generator->create_record((object)['owneruserid' => $this->u1->id, 'contextid' => $this->c1context->id]);$this->generator->create_record((object)['owneruserid' => $this->u1->id, 'contextid' => $this->c2context->id]);$this->generator->create_record((object)['owneruserid' => $this->u2->id, 'contextid' => $this->c1context->id]);$this->generator->create_record((object)['owneruserid' => $this->u2->id, 'contextid' => $this->c2context->id]);$this->search->index();$this->setAdminUser();}/*** tearDown** @return void*/public function tearDown(): void {// Call parent tearDown() first.parent::tearDown();// For unit tests before PHP 7, teardown is called even on skip. So only do our teardown if we did setup.if ($this->generator) {// Moodle DML freaks out if we don't teardown the temp table after each run.$this->generator->teardown();$this->generator = null;}}/*** Test fetching contexts for a given user ID.*/public function test_get_contexts_for_userid(): void {// Ensure both contexts are found for both users.$expected = [$this->c1context->id, $this->c2context->id];sort($expected);// User 1.$contextlist = provider::get_contexts_for_userid($this->u1->id);$this->assertCount(2, $contextlist);$actual = $contextlist->get_contextids();sort($actual);$this->assertEquals($expected, $actual);// User 2.$contextlist = provider::get_contexts_for_userid($this->u2->id);$this->assertCount(2, $contextlist);$actual = $contextlist->get_contextids();sort($actual);$this->assertEquals($expected, $actual);}/*** Test fetching user IDs for a given context.*/public function test_get_users_in_context(): void {$component = 'search_simpledb';// Ensure both users are found for both contexts.$expected = [$this->u1->id, $this->u2->id];sort($expected);// User 1.$userlist = new \core_privacy\local\request\userlist($this->c1context, $component);provider::get_users_in_context($userlist);$this->assertCount(2, $userlist);$actual = $userlist->get_userids();sort($actual);$this->assertEquals($expected, $actual);// User 2.$userlist = new \core_privacy\local\request\userlist($this->c2context, $component);provider::get_users_in_context($userlist);$this->assertCount(2, $userlist);$actual = $userlist->get_userids();sort($actual);$this->assertEquals($expected, $actual);}/*** Test export user data.** @return null*/public function test_export_user_data(): void {global $DB;$contextlist = new \core_privacy\local\request\approved_contextlist($this->u1, 'search_simpledb',[$this->c1context->id]);provider::export_user_data($contextlist);$writer = \core_privacy\local\request\writer::with_context($this->c1context);$this->assertTrue($writer->has_any_data());$u1c1 = $DB->get_record('search_simpledb_index', ['userid' => $this->u1->id, 'contextid' => $this->c1context->id]);$data = $writer->get_data([get_string('search', 'search'), $u1c1->docid]);$this->assertEquals($this->c1context->get_context_name(true, true), $data->context);$this->assertEquals('vi', $data->title);$this->assertEquals('va', $data->content);$this->assertEquals('san', $data->description1);$this->assertEquals('jose', $data->description2);}/*** Test delete search for context.** @return null*/public function test_delete_data_for_all_users(): void {global $DB;$this->assertEquals(8, $DB->count_records('search_simpledb_index'));provider::delete_data_for_all_users_in_context($this->c1context);$this->assertEquals(0, $DB->count_records('search_simpledb_index', ['contextid' => $this->c1context->id]));$this->assertEquals(4, $DB->count_records('search_simpledb_index'));$u2context = \context_user::instance($this->u2->id);provider::delete_data_for_all_users_in_context($u2context);$this->assertEquals(0, $DB->count_records('search_simpledb_index', ['contextid' => $u2context->id]));$this->assertEquals(2, $DB->count_records('search_simpledb_index'));}/*** Test delete search for user.** @return null*/public function test_delete_data_for_user(): void {global $DB;$contextlist = new \core_privacy\local\request\approved_contextlist($this->u1, 'search_simpledb',[$this->c1context->id]);provider::delete_data_for_user($contextlist);$select = 'contextid = :contextid AND (owneruserid = :owneruserid OR userid = :userid)';$params = ['contextid' => $this->c1context->id, 'owneruserid' => $this->u1->id, 'userid' => $this->u1->id];$this->assertEquals(0, $DB->count_records_select('search_simpledb_index', $select, $params));$this->assertEquals(2, $DB->count_records('search_simpledb_index', ['contextid' => $this->c1context->id]));$this->assertEquals(6, $DB->count_records('search_simpledb_index'));$contextlist = new \core_privacy\local\request\approved_contextlist($this->u2, 'search_simpledb',[$this->c2context->id]);provider::delete_data_for_user($contextlist);$select = 'contextid = :contextid AND (owneruserid = :owneruserid OR userid = :userid)';$params = ['contextid' => $this->c2context->id, 'owneruserid' => $this->u2->id, 'userid' => $this->u2->id];$this->assertEquals(0, $DB->count_records_select('search_simpledb_index', $select, $params));$this->assertEquals(2, $DB->count_records('search_simpledb_index', ['contextid' => $this->c2context->id]));$this->assertEquals(4, $DB->count_records('search_simpledb_index'));}/*** Test deleting data for an approved userlist.*/public function test_delete_data_for_users(): void {global $DB;$component = 'search_simpledb';$select = 'contextid = :contextid AND (owneruserid = :owneruserid OR userid = :userid)';// Ensure expected amount of data for both users exists in each context.$this->assertEquals(4, $DB->count_records('search_simpledb_index', ['contextid' => $this->c1context->id]));$this->assertEquals(4, $DB->count_records('search_simpledb_index', ['contextid' => $this->c2context->id]));// Delete user 1's data in context 1.$approveduserids = [$this->u1->id];$approvedlist = new \core_privacy\local\request\approved_userlist($this->c1context, $component, $approveduserids);provider::delete_data_for_users($approvedlist);$params = ['contextid' => $this->c1context->id, 'owneruserid' => $this->u1->id, 'userid' => $this->u1->id];$this->assertEquals(0, $DB->count_records_select('search_simpledb_index', $select, $params));// Ensure user 2's data in context 1 is retained.$params = ['contextid' => $this->c1context->id, 'owneruserid' => $this->u2->id, 'userid' => $this->u2->id];$this->assertEquals(2, $DB->count_records_select('search_simpledb_index', $select, $params));// Ensure both users' data in context 2 is retained.$params = ['contextid' => $this->c2context->id, 'owneruserid' => $this->u1->id, 'userid' => $this->u1->id];$this->assertEquals(2, $DB->count_records_select('search_simpledb_index', $select, $params));$params = ['contextid' => $this->c2context->id, 'owneruserid' => $this->u2->id, 'userid' => $this->u2->id];$this->assertEquals(2, $DB->count_records_select('search_simpledb_index', $select, $params));}/*** Mssql with fulltext support requires manual updates.** @return bool*/private function requires_manual_index_update() {global $DB;return ($DB->get_dbfamily() === 'mssql' && $DB->is_fulltext_search_supported());}}