MDL-53226 search_simpledb: Adding clumsy search
authorDavid Monllao <davidm@moodle.com>
Tue, 1 Mar 2016 16:03:03 +0000 (00:03 +0800)
committerDavid Monllao <davidm@moodle.com>
Tue, 20 Mar 2018 17:33:03 +0000 (18:33 +0100)
lib/classes/plugin_manager.php
search/engine/simpledb/classes/engine.php [new file with mode: 0644]
search/engine/simpledb/db/install.xml [new file with mode: 0644]
search/engine/simpledb/lang/en/search_simpledb.php [new file with mode: 0644]
search/engine/simpledb/tests/engine_test.php [new file with mode: 0644]
search/engine/simpledb/version.php [new file with mode: 0644]
search/engine/solr/lang/en/search_solr.php
search/engine/solr/tests/engine_test.php

index 7af9689..fca4ec8 100644 (file)
@@ -1884,7 +1884,7 @@ class core_plugin_manager {
             ),
 
             'search' => array(
-                'solr'
+                'simpledb', 'solr'
             ),
 
             'scormreport' => array(
diff --git a/search/engine/simpledb/classes/engine.php b/search/engine/simpledb/classes/engine.php
new file mode 100644 (file)
index 0000000..47d41b1
--- /dev/null
@@ -0,0 +1,260 @@
+<?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/>.
+
+/**
+ * Simple moodle database engine.
+ *
+ * @package    search_simpledb
+ * @copyright  2016 David Monllao {@link http://www.davidmonllao.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace search_simpledb;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Simple moodle database engine.
+ *
+ * @package    search_simpledb
+ * @copyright  2016 David Monllao {@link http://www.davidmonllao.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class engine extends \core_search\engine {
+
+    /**
+     * Prepares a Solr query, applies filters and executes it returning its results.
+     *
+     * @throws \core_search\engine_exception
+     * @param  stdClass     $filters Containing query and filters.
+     * @param  array        $usercontexts Contexts where the user has access. True if the user can access all contexts.
+     * @return \core_search\document[] Results or false if no results
+     */
+    public function execute_query($filters, $usercontexts) {
+        global $DB, $USER;
+
+        // Let's keep these changes internal.
+        $data = clone $filters;
+
+        $serverstatus = $this->is_server_ready();
+        if ($serverstatus !== true) {
+            throw new \core_search\engine_exception('engineserverstatus', 'search');
+        }
+
+        $sql = 'SELECT * FROM {search_simpledb_index} WHERE ';
+        $params = array();
+
+        // To store all conditions we will add to where.
+        $ands = array();
+
+        // Get results only available for the current user.
+        $ands[] = '(owneruserid = ? OR owneruserid = ?)';
+        $params = array_merge($params, array(\core_search\manager::NO_OWNER_ID, $USER->id));
+
+        // Restrict it to the context where the user can access, we want this one cached.
+        // If the user can access all contexts $usercontexts value is just true, we don't need to filter
+        // in that case.
+        if ($usercontexts && is_array($usercontexts)) {
+            // Join all area contexts into a single array and implode.
+            $allcontexts = array();
+            foreach ($usercontexts as $areaid => $areacontexts) {
+                if (!empty($data->areaid) && ($areaid !== $data->areaid)) {
+                    // Skip unused areas.
+                    continue;
+                }
+                foreach ($areacontexts as $contextid) {
+                    // Ensure they are unique.
+                    $allcontexts[$contextid] = $contextid;
+                }
+            }
+            if (empty($allcontexts)) {
+                // This means there are no valid contexts for them, so they get no results.
+                return array();
+            }
+
+            list($contextsql, $contextparams) = $DB->get_in_or_equal($allcontexts);
+            $ands[] = 'contextid ' . $contextsql;
+            $params = array_merge($params, $contextparams);
+        }
+
+        // Course id filter.
+        if (!empty($data->courseids)) {
+            list($conditionsql, $conditionparams) = $DB->get_in_or_equal($data->courseids);
+            $ands[] = 'courseid ' . $conditionsql;
+            $params = array_merge($params, $conditionparams);
+        }
+
+        // Area id filter.
+        if (!empty($data->areaid)) {
+            list($conditionsql, $conditionparams) = $DB->get_in_or_equal($data->areaid);
+            $ands[] = 'areaid ' . $conditionsql;
+            $params = array_merge($params, $conditionparams);
+        }
+
+        if (!empty($data->title)) {
+            list($conditionsql, $conditionparams) = $DB->get_in_or_equal($data->title);
+            $ands[] = 'title ' . $conditionsql;
+            $params = array_merge($params, $conditionparams);
+        }
+
+        if (!empty($data->timestart)) {
+            $ands[] = 'modified >= ?';
+            $params[] = $data->timestart;
+        }
+        if (!empty($data->timeend)) {
+            $ands[] = 'modified <= ?';
+            $params[] = $data->timeend;
+        }
+
+        // And finally the main query after applying all AND filters.
+        $ands[] = '(' .
+            $DB->sql_like('title', '?', false, false) . ' OR ' .
+            $DB->sql_like('content', '?', false, false) . ' OR ' .
+            $DB->sql_like('description1', '?', false, false) . ' OR ' .
+            $DB->sql_like('description2', '?', false, false) .
+            ')';
+        $params[] = '%' . $data->q . '%';
+        $params[] = '%' . $data->q . '%';
+        $params[] = '%' . $data->q . '%';
+        $params[] = '%' . $data->q . '%';
+
+        $recordset = $DB->get_recordset_sql($sql . implode(' AND ', $ands), $params, 0, \core_search\manager::MAX_RESULTS);
+
+        $numgranted = 0;
+
+        if (!$recordset->valid()) {
+            return array();
+        }
+
+        // Iterate through the results checking its availability and whether they are available for the user or not.
+        $docs = array();
+        foreach ($recordset as $docdata) {
+            if (!$searcharea = $this->get_search_area($docdata->areaid)) {
+                continue;
+            }
+
+            // Switch id back to the document id.
+            $docdata->id = $docdata->docid;
+            unset($docdata->docid);
+
+            $access = $searcharea->check_access($docdata->itemid);
+            switch ($access) {
+                case \core_search\manager::ACCESS_DELETED:
+                    $this->delete_by_id($docdata->id);
+                    break;
+                case \core_search\manager::ACCESS_DENIED:
+                    break;
+                case \core_search\manager::ACCESS_GRANTED:
+                    $numgranted++;
+                    $docs[] = $this->to_document($searcharea, (array)$docdata);
+                    break;
+            }
+
+            // This should never happen.
+            if ($numgranted >= \core_search\manager::MAX_RESULTS) {
+                $docs = array_slice($docs, 0, \core_search\manager::MAX_RESULTS, true);
+                break;
+            }
+        }
+        $recordset->close();
+
+        return $docs;
+    }
+
+    /**
+     * Adds a document to the search engine.
+     *
+     * This does not commit to the search engine.
+     *
+     * @param \core_search\document $document
+     * @param bool $fileindexing True if file indexing is to be used
+     * @return bool False if the file was skipped or failed, true on success
+     */
+    public function add_document($document, $fileindexing = false) {
+        global $DB;
+
+        $doc = (object)$document->export_for_engine();
+
+        // Moodle's ids using DML are always autoincremented.
+        $doc->docid = $doc->id;
+        unset($doc->id);
+
+        $id = $DB->get_field('search_simpledb_index', 'id', array('docid' => $doc->docid));
+        try {
+            if ($id) {
+                $doc->id = $id;
+                $DB->update_record('search_simpledb_index', $doc);
+            } else {
+                $DB->insert_record('search_simpledb_index', $doc);
+            }
+
+        } catch (dml_exception $ex) {
+            debugging('dml error while trying to insert document with id ' . $doc->docid . ': ' . $e->getMessage(),
+                DEBUG_DEVELOPER);
+        }
+
+        return true;
+    }
+
+    /**
+     * Deletes the specified document.
+     *
+     * @param string $id The document id to delete
+     * @return void
+     */
+    public function delete_by_id($id) {
+        global $DB;
+        $DB->delete_records('search_simpledb_index', array('docid' => $id));
+    }
+
+    /**
+     * Delete all area's documents.
+     *
+     * @param string $areaid
+     * @return void
+     */
+    public function delete($areaid = null) {
+        global $DB;
+        if ($areaid) {
+            $DB->delete_records('search_simpledb_index', array('areaid' => $areaid));
+        } else {
+            $DB->delete_records('search_simpledb_index');
+        }
+    }
+
+    /**
+     * Checks that the required table was installed.
+     *
+     * @return true|string Returns true if all good or an error string.
+     */
+    public function is_server_ready() {
+        global $DB;
+        if (!$DB->get_manager()->table_exists('search_simpledb_index')) {
+            return 'search_simpledb_index table does not exist';
+        }
+
+        return true;
+    }
+
+    /**
+     * It is always installed.
+     *
+     * @return true
+     */
+    public function is_installed() {
+        return true;
+    }
+}
diff --git a/search/engine/simpledb/db/install.xml b/search/engine/simpledb/db/install.xml
new file mode 100644 (file)
index 0000000..2139331
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<XMLDB PATH="search/engine/simpledb/db" VERSION="20160408" COMMENT="XMLDB file for Moodle search/engine/simpledb"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
+>
+  <TABLES>
+    <TABLE NAME="search_simpledb_index" COMMENT="search_simpledb table containing the index data.">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+        <FIELD NAME="docid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="title" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="content" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="areaid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="type" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="owneruserid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="modified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="description1" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="description2" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+        <KEY NAME="docid" TYPE="unique" FIELDS="docid"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="owneruserid-contextid" UNIQUE="false" FIELDS="owneruserid, contextid" COMMENT="Query filters if no extra search filters are applied"/>
+      </INDEXES>
+    </TABLE>
+  </TABLES>
+</XMLDB>
\ No newline at end of file
diff --git a/search/engine/simpledb/lang/en/search_simpledb.php b/search/engine/simpledb/lang/en/search_simpledb.php
new file mode 100644 (file)
index 0000000..5063a88
--- /dev/null
@@ -0,0 +1,27 @@
+<?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/>.
+
+/**
+ * Strings for component 'search_simpledb'.
+ *
+ * @package   search_simpledb
+ * @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['pluginname'] = 'Simple search';
+$string['searchinfo'] = 'Search queries';
+$string['searchinfo_help'] = 'Enter the search query.';
diff --git a/search/engine/simpledb/tests/engine_test.php b/search/engine/simpledb/tests/engine_test.php
new file mode 100644 (file)
index 0000000..fa37e19
--- /dev/null
@@ -0,0 +1,264 @@
+<?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/>.
+
+/**
+ * Simple db search engine tests.
+ *
+ * @package     search_simpledb
+ * @category    phpunit
+ * @copyright   2016 David Monllao {@link http://www.davidmonllao.com}
+ * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+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');
+
+/**
+ * Simple search engine base unit tests.
+ *
+ * @package     search_simpledb
+ * @category    phpunit
+ * @copyright   2016 David Monllao {@link http://www.davidmonllao.com}
+ * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class search_simpledb_engine_testcase extends advanced_testcase {
+
+    /**
+     * @var \core_search::manager
+     */
+    protected $search = null;
+
+    public function setUp() {
+        $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.
+        $searchengine = new \search_simpledb\engine();
+        $this->search = testable_core_search::instance($searchengine);
+        $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
+        $this->search->add_search_area($areaid, new core_mocksearch\search\role_capabilities());
+    }
+
+    public function test_index() {
+        global $DB;
+
+        $noneditingteacherid = $DB->get_field('role', 'id', array('shortname' => 'teacher'));
+
+        // Data gets into the search engine.
+        $this->assertTrue($this->search->index());
+
+        // Not anymore as everything was already added.
+        sleep(1);
+        $this->assertFalse($this->search->index());
+
+        assign_capability('moodle/course:renameroles', CAP_ALLOW, $noneditingteacherid, context_system::instance()->id);
+        accesslib_clear_all_caches_for_unit_testing();
+
+        // Indexing again once there is new data.
+        $this->assertTrue($this->search->index());
+    }
+
+    /**
+     * Test search filters.
+     *
+     * @return void
+     */
+    public function test_search() {
+        global $USER, $DB;
+
+        $this->setAdminUser();
+
+        $noneditingteacherid = $DB->get_field('role', 'id', array('shortname' => 'teacher'));
+
+        $this->search->index();
+
+        // Check that docid - id is respected.
+        $rolecaps = $DB->get_records('role_capabilities', array('capability' => 'moodle/course:renameroles'));
+        $rolecap = reset($rolecaps);
+        $rolecap->timemodified = time();
+        $DB->update_record('role_capabilities', $rolecap);
+
+        $this->search->index();
+
+        $querydata = new stdClass();
+        $querydata->q = 'message';
+        $results = $this->search->search($querydata);
+        $this->assertCount(2, $results);
+
+        // Based on core_mocksearch\search\indexer.
+        $this->assertEquals($USER->id, $results[0]->get('userid'));
+        $this->assertEquals(\context_system::instance()->id, $results[0]->get('contextid'));
+
+        // Do a test to make sure we aren't searching non-query fields, like areaid.
+        $querydata->q = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
+        $this->assertCount(0, $this->search->search($querydata));
+        $querydata->q = 'message';
+
+        sleep(1);
+        $beforeadding = time();
+        sleep(1);
+        assign_capability('moodle/course:renameroles', CAP_ALLOW, $noneditingteacherid, context_system::instance()->id);
+        accesslib_clear_all_caches_for_unit_testing();
+        $this->search->index();
+
+        // Timestart.
+        $querydata->timestart = $beforeadding;
+        $this->assertCount(2, $this->search->search($querydata));
+
+        // Timeend.
+        unset($querydata->timestart);
+        $querydata->timeend = $beforeadding;
+        $this->assertCount(1, $this->search->search($querydata));
+
+        // Title.
+        unset($querydata->timeend);
+        $querydata->title = 'moodle/course:renameroles roleid 1';
+        $this->assertCount(1, $this->search->search($querydata));
+
+        // Course IDs.
+        unset($querydata->title);
+        $querydata->courseids = array(SITEID + 1);
+        $this->assertCount(0, $this->search->search($querydata));
+
+        $querydata->courseids = array(SITEID);
+        $this->assertCount(3, $this->search->search($querydata));
+
+        // Check that index contents get updated.
+        $DB->delete_records('role_capabilities', array('capability' => 'moodle/course:renameroles'));
+        $this->search->index(true);
+        unset($querydata->title);
+        $querydata->q = '*renameroles*';
+        $this->assertCount(0, $this->search->search($querydata));
+    }
+
+    public function test_delete() {
+        $this->search->index();
+
+        $querydata = new stdClass();
+        $querydata->q = 'message';
+
+        $this->assertCount(2, $this->search->search($querydata));
+
+        $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
+        $this->search->delete_index($areaid);
+        $this->assertCount(0, $this->search->search($querydata));
+    }
+
+    public function test_alloweduserid() {
+        $engine = $this->search->get_engine();
+        $area = new core_mocksearch\search\role_capabilities();
+
+        // Get the first record for the recordset.
+        $recordset = $area->get_recordset_by_timestamp();
+        foreach ($recordset as $r) {
+            $record = $r;
+            break;
+        }
+        $recordset->close();
+
+        // Get the doc and insert the default doc.
+        $doc = $area->get_document($record);
+        $engine->add_document($doc);
+
+        $users = array();
+        $users[] = $this->getDataGenerator()->create_user();
+        $users[] = $this->getDataGenerator()->create_user();
+        $users[] = $this->getDataGenerator()->create_user();
+
+        // Add a record that only user 100 can see.
+        $originalid = $doc->get('id');
+
+        // Now add a custom doc for each user.
+        foreach ($users as $user) {
+            $doc = $area->get_document($record);
+            $doc->set('id', $originalid.'-'.$user->id);
+            $doc->set('owneruserid', $user->id);
+            $engine->add_document($doc);
+        }
+
+        $engine->area_index_complete($area->get_area_id());
+
+        $querydata = new stdClass();
+        $querydata->q = 'message';
+        $querydata->title = $doc->get('title');
+
+        // We are going to go through each user and see if they get the original and the owned doc.
+        foreach ($users as $user) {
+            $this->setUser($user);
+
+            $results = $this->search->search($querydata);
+            $this->assertCount(2, $results);
+
+            $owned = 0;
+            $notowned = 0;
+
+            // We don't know what order we will get the results in, so we are doing this.
+            foreach ($results as $result) {
+                $owneruserid = $result->get('owneruserid');
+                if (empty($owneruserid)) {
+                    $notowned++;
+                    $this->assertEquals(0, $owneruserid);
+                    $this->assertEquals($originalid, $result->get('id'));
+                } else {
+                    $owned++;
+                    $this->assertEquals($user->id, $owneruserid);
+                    $this->assertEquals($originalid.'-'.$user->id, $result->get('id'));
+                }
+            }
+
+            $this->assertEquals(1, $owned);
+            $this->assertEquals(1, $notowned);
+        }
+
+        // Now test a user with no owned results.
+        $otheruser = $this->getDataGenerator()->create_user();
+        $this->setUser($otheruser);
+
+        $results = $this->search->search($querydata);
+        $this->assertCount(1, $results);
+
+        $this->assertEquals(0, $results[0]->get('owneruserid'));
+        $this->assertEquals($originalid, $results[0]->get('id'));
+    }
+
+    public function test_delete_by_id() {
+        // First get files in the index.
+        $this->search->index();
+        $engine = $this->search->get_engine();
+
+        $querydata = new stdClass();
+
+        // Then search to make sure they are there.
+        $querydata->q = 'moodle/course:renameroles';
+        $results = $this->search->search($querydata);
+        $this->assertCount(2, $results);
+
+        $first = reset($results);
+        $deleteid = $first->get('id');
+
+        $engine->delete_by_id($deleteid);
+
+        // Check that we don't get a result for it anymore.
+        $results = $this->search->search($querydata);
+        $this->assertCount(1, $results);
+        $result = reset($results);
+        $this->assertNotEquals($deleteid, $result->get('id'));
+    }
+}
diff --git a/search/engine/simpledb/version.php b/search/engine/simpledb/version.php
new file mode 100644 (file)
index 0000000..10e5a8c
--- /dev/null
@@ -0,0 +1,29 @@
+<?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/>.
+
+/**
+ * Version info.
+ *
+ * @package search_simpledb
+ * @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version = 2016030100;
+$plugin->requires = 2015111000;
+$plugin->component = 'search_simpledb';
index 6addfea..e87576c 100644 (file)
@@ -17,7 +17,7 @@
 /**
  * Strings for component 'search_solr'.
  *
- * @package   core_search
+ * @package   search_solr
  * @copyright Prateek Sachan {@link http://prateeksachan.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 7a4bcde..f9b76c5 100644 (file)
@@ -30,7 +30,7 @@
  * - define('TEST_SEARCH_SOLR_KEYPASSWORD', '');
  * - define('TEST_SEARCH_SOLR_CAINFOCERT', '');
  *
- * @package     core_search
+ * @package     search_solr
  * @category    phpunit
  * @copyright   2015 David Monllao {@link http://www.davidmonllao.com}
  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -46,7 +46,7 @@ require_once($CFG->dirroot . '/search/engine/solr/tests/fixtures/testable_engine
 /**
  * Solr search engine base unit tests.
  *
- * @package     core_search
+ * @package     search_solr
  * @category    phpunit
  * @copyright   2015 David Monllao {@link http://www.davidmonllao.com}
  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later